理解一个问题与讲明白一个问题哪个更困难?
什么是 CA ?
CA(Certificate Authority) 是证书的签发机构,它是 PKI(Public key infrastructure,公钥基础设施) 的核心。CA 是负责签发证书、认证证书、管理已颁发证书的机关。它要制定政策和具体步骤来验证、识别用户身份,并对用户证书进行签名,以确保证书持有者的身份和公钥的拥有权。
常见的 CA 机构有 Let’s Encrypt、CAcert.org、Comodo、DigiCert、GlobalSign、Verisign等。
什么是根证书?
根证书(root certificate)是属于根证书颁发机构(CA)的公钥证书,是在公开金钥基础建设中,信任链的起点。任何人都可以得到 CA 的证书(含公钥),用以验证它所签发的证书。
证书链是形成一个以其根证书为顶层的树状结构,通过根证书与中间证书(树干)可以为网站签发无数的叶证书(树叶),我们的电脑只需预装有限的根证书,就可以辨别无数网站的证书是否由可信根证书签发,从而验证安全性。
根证书是如何产生的?
钥匙典礼:凭证机构自签一张新的根凭证时,需要产生一对公开金钥及私有密钥,这个过程在公证人、律师及录影系统监察下经过一系列严谨的程序,在高度防护的设施内进行。
根证书作为自签证书,但是获得广泛认可,通常已预先安装在各种软件(包括操作系统、浏览器、电邮软件等),作为信任链的起点,来自于公认可靠的政府机关(如香港邮政)、软件公司(如 Google、Let’s Encrypt)等,与各大软件商透过严谨的核认程序才在不同的软件广泛部署。由于部署程序复杂费时,需要行政人员的授权及机构法人身份的核认,一张根证书有效期可能长达十年以上。
我们可以在 Mac 中的 Keychain Access 中查到这些内置根证书。
由于根凭证在信任链中的重要角色,一旦凭证机构的私钥外泄,将可能导致整个信任链被摧毁,影响广及众多客户,所以认证机构会使用各种方法保护根凭证,例如硬件安全模组。有些储存私钥的电脑甚至平时不会连线,只在固定的安排下,经过一系列严谨的行政流程重重把关,才会取出私钥为客户签章凭证。在信任链设计中,绝大部份的根凭证都不会直接为客户签章,而是先签章一个(或多个)中继凭证,再由中继凭证为客户签章,这可以加强控管能力及控制一旦签章私钥被泄时的损失。
证书中都包含哪些信息?
证书需要保证用户之间在网上传递信息的安全性、真实性、可靠性、完整性和不可抵赖性。
证书的内容包括:电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等等。目前,证书的格式和验证方法普遍遵循 X.509 国际标准,其内容格式如下
- 版本:现行通用版本是 V3
- 序号:用以辨识每一张凭证,特别在撤消凭证的时候有用
- 主体:拥有此凭证的法人或自然人身份或机器,包括:
- 国家(C,Country)
- 州 / 省(S,State)
- 地域 / 城市(L,Location)
- 组织 / 单位(O,Organization)
- 通用名称 (CN,Common Name):在 TLS 应用上,此栏位一般是 网域
- 发行者:以数位签章形式签署此凭证的数字证书认证机构
- 有效期开始时间:此凭证的有效开始时间,在此前该凭证并未生效
- 有效期结束时间:此凭证的有效结束时间,在此后该凭证作废
- 公钥用途:指定凭证上公钥的用途,例如数字签名、服务器验证、用户端验证等
- 公钥
- 公钥指纹
- 数位签章
- 数位签章演算法
- 主体别名:例如一个网站可能会有多个网域(www.wikipedia.org, zh.wikipedia.org, zh.m.wikipedia.org 都是维基百科)、一个组织可能会有多个网站(*.wikipedia.org, *.wikibooks.org, *.wikidata.org 都是维基媒体基金会旗下的网域),不同的网域可以一并使用同一张凭证,方便实作应用及管理
为什么证书中的加密算法经常是ECDSA with SHA-512
,而不是单一算法?
通常我们先对消息进行哈希,得到一个消息摘要,然后再用私钥对该摘要进行签名,我们通过公钥对该消息摘要的签名验证即可,这也是为什么我们经常看到的非对称加密是ECDSA with SHA-512
证书的作用是什么?
使用数字证书实现身份识别和电子信息加密。数字证书中含有密钥对(公钥和私钥)所有者的识别信息,通过验证识别信息的真伪实现对证书持有者身份的认证。
CA 给认证者颁发了什么?公钥?私钥?还是签名?
用户若欲取得证书,应先向 CA 提出申请,CA 判明申请者的身份后,为之分配一个公钥,并将该公钥与其身份信息绑定,为该整体签字,签字后的整体即为证书,发还给申请者。
简而言之,CA 用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。
向 CA 申领证书的流程是怎样的?
证书申领的具体流程如下:
- 创建公私钥
- 创建 CSR,其中需要包含域名与公钥,并用私钥签名
- 发送 CSR 至 CA
- CA 通过检查DNS,检查黄页,打电话等方式验证 CSR 中的是否真实
- 如果验证通过,则 CA 签发证书
举个例子:
6. 鲍伯在自己的机器上使用密码学安全伪随机数生成器产生一对足够强的密钥,鲍伯的私钥不会向任何人传送。
7. 鲍伯把他的公钥,连同主体讯息、使用目的等组成凭证签署请求,传送给认证机构伊凡。
8. 伊凡(用另外一些渠道)核实鲍伯的身份(如验证公司主体、营业执照等方式)。
9. 如果伊凡信任这个请求,他便使用鲍伯的公钥和主体讯息,加上凭证有效期、用途等限制条件,组成凭证的基本资料。
10. 伊凡用自己的私钥对鲍勃的公钥加上数字签名并生成证书。
11. 伊凡把生成的凭证传送给鲍伯(伊凡也可以透过证书透明度公布他签发了新的证书)。
证书的存储格式是怎样的?
电子证书可以二进制或 Base64 形式储存,常见的二进制文件扩展名有 .cer
、.crt
、.der
,Base64 的文件扩展名则通常是 .pem
。如果把证书和私钥一起储存,则可以使用 PKCS#12(.p12
)格式
客户浏览器内置 CA 证书是在浏览器还是在操作系统?是只内置根证书吗?
根证书没有上层机构再为其本身作数位签章,所以都是自签证书。许多应用软件(例如操作系统、网页浏览器)会预先安装可被信任的根证书。没有证书存储的浏览器则依赖于操作系统的证书存储。
根证书也是存在有效期的,如何更新根证书?
根证书通常有十几年或几十年的有效期,所以同样会过期,根证书会通过浏览器或者操作系统的升级来完成。
用户如何对证书进行鉴别?
如果一个用户想鉴别另一个证书的真伪,他就用 CA 的公钥对那个证书上的签字进行验证,一旦验证通过,该证书就被认为是有效的。
- 鲍伯可以随便把凭证向外发布。
- 鲍伯与爱丽丝事先可能互不认识,但鲍伯与爱丽丝都信任伊凡,爱丽丝使用认证机构伊凡的公钥验证数字签名,如果验证成功,便可以信任鲍勃的公钥是真正属于鲍伯的。
- 爱丽丝可以使用凭证上的鲍勃的公钥加密明文,得到密文并传送给鲍伯。
- 鲍伯可以可以用自己的私钥把密文解密,得到明文。
由于浏览器或操作系统内置了根证书,这些根证书是值得信任的,因此用户从最末级的证书开始逐步认证,判断最终的证书是否符合系统内嵌的根证书即可。
如果某个证书在有效期内被吊销,该如何处理?
假如 X 银行的私钥泄露,则可能会使客户资金受损,此时需要紧急吊销其证书,应该怎么操作呢?这篇文章 ☞你不在意的 HTTPS 证书吊销机制 讲的挺清楚的,我就不班门弄斧了。
公钥的作用是什么?
- 消息签名
- 消息加密,仅私钥持有者才能解密消息
RSA 可以进行加密和签名,而 ECDSA 只能进行签名。
既然公私钥可以验证对方身份,为什么我们还需要证书呢?
虽然公私钥可以完成身份的验证,但我们并不能确定它们是否属于特定实体,这就是我们使用“证书”的原因。证书中包含了公钥、实体信息、有效期、可信方签名,因此我们可以验证对方的真实身份。
RSA如何实现数字签名
信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行 RSA 算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在传递过程中未被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。(将某个人与某人所说的话绑定在一起进行 hash,如果其中任何一项被篡改,则 hash 值就会不一致(防篡改);通过对方的特征,如公钥,确定对方无法抵赖)
HTTPS握手过程
以下握手过程来自《图解 HTTP》
- 客户端通过发送 Client Hello 报文开始 SSL 通信。报文中包含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。
- 服务器可进行 SSL通信时,会以 Server Hello 报文作为应答。和客户端一样,在报文中包含 SSL 版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。
- 之后服务器发送 Certificate 报文。报文中包含公开密钥证书,客户端进行证书的信任链验证,认证过程如下图,授权密钥标识符与其上级主题标识符相匹配,根证书的主题标识符与授权密钥标识符相同
- 最后服务器发送 Server Hello Done 报文通知客户端,最初阶段的 SSL握手协商部分结束。
- SSL第一次握手结束之后,客户端以 Client Key Exchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-master secret 的随机密码串。该报文已用步骤 3 中的公开密钥进行加密。
- 接着客户端继续发送 Change Cipher Spec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。
- 客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。
- 服务器同样发送 Change Cipher Spec 报文。
- 服务器同样发送 Finished 报文。
- 服务器和客户端的 Finished 报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。
- 应用层协议通信,即发送 HTTP 响应。
- 最后由客户端断开连接。断开连接时,发送 close_notify 报文。上图做了一些省略,这步之后再发送 TCP FIN 报文来关闭与 TCP的通信。
在以上流程中,应用层发送数据时会附加一种叫做 MAC(Message Authentication Code)的报文摘要。MAC 能够查知报文是否遭到篡改,从而保护报文的完整性。
为什么仅在握手阶段使用 TLS,而不一直使用TLS 通信呢?
由于非对称加密缓慢并增加数据包的大小,因此几乎所有协议(如 TLS、SSH)仅在建立安全连接时使用非对称加密,而在数据传输阶段使用对称加密。
HTTPS 会有中间人攻击(MIMT)问题吗?
答案是会,前提是中间人将其证书植入通讯方的主机上。我们以用户 C 与服务端 S 为例。
- 假设C的电脑已在较早前被M安装了特定的根凭证,M拥有对应的私钥
- 当C尝试与S建立安全连线时,M以代理服务器的身份先行收到连线请求
- M暂时搁下C的请求,转而建立另一条连线向S请求他的电子证书
- S的电子证书已得到一个受广泛认可的认证机构数位签章,如果M如实转交给C,一切都不会有问题
- 但M使用自己的私钥签发一个电子证书,证书上主体名称声称是属于S,并交给C,而S不曾知道
- C验证收到的电子证书,根据其信任链,她找到签发的根证书
- 她发现自己的电脑中已安装并信任这样一个根证书,便信以为真,开始使用证书上的公钥与S的秘密通讯
- 其实该根证书就是M早前安装上去用以欺骗C,这时M能够利用自己的私钥解密C传出的密文,并即时再用先前收到、S真正的电子证书上的公钥再加密,并传给S
- S收到密文时不虞有诈,他能够用自己的私钥解密M传送过来的密文
这也就是我们使用 Charles 等抓包工具抓取 HTTPS 包时为什么要安装软件提供证书的原因了。
那么,如何避免 HTTPS 的 MIMT 呢?要避免中间人攻击置换假冒的电子证书,HTTPS 网站可以使用 HPKP 指明其固定的公钥,或者通过证书透明度验证证书,让中间人的欺诈证书无法使用。验证证书是否被吊销可以采用 CRLs (certificate revocation lists)或者 OCSP 方式。CRLs(黑名单)就是定期从 CA 下载一个名单列表,里面有吊销的证书序列号,自己在本地比对一下就行,优点是效率高,缺点是不实时;OCSP 是实时连接 CA 去验证,优点是实时,缺点是效率不高。
为什么有些网站会有证书不受信任的警告?
最为著名的案例就是12306刚上线时的页面警告
造成这个原因就是 12306 的证书是自签的,而非 CA 机构签发的,这就导致信任链条无法完成,从而发出警告。而当时 12306 对该问题的解决方案是让用户自行安装根证书
在 2017 年,12306 就将证书更换了 CA 机构签发的,从而彻底解决了该问题。
数字签名的优势是什么?
数位凭证的其中一个最主要好处是在认证拥有者身分期间,拥有者的敏感个人资料(如出生日期、身分证号码等)并不会传输至索取资料者的电脑系统上。透过这种资料交换模式,拥有者既可证实自己的身分,亦不用过度披露个人资料,对保障电脑服务存取双方皆有好处。
小结
从 HTTPS 的流程中我们可以看到,整个认证流程是中心化的,CA 即为整个流程的中心,就像中央银行一样,一旦 CA 私钥泄露,将造成灾难性后果。如果采用去中心化该如何认证呢?我想去中心化的核心思想在于所有的参与者都清楚发生的每一件事,这样就让少数别有用心的人拒之门外,即少数服从多数。
正如去中心化技术的代表 Git 和区块链一样,每个参与者都有创世以来的所有操作记录,如果有人想作弊,那就要篡改掉至少 51% 的系统成员才会成功,这个成本无疑是巨大的。
在这种去中心化的模式下,缺点也是显而易见的,即每个人都要记录所有被证实的消息,而中心化则可以让参与者轻装上阵。世间安得两全法,轻量又能去中心?
SSL vs TLS
SSL为 TLS 的前身,由于安全问题已被弃用,请使用 TLS 1.2 及以上版本
PGP 与 GPG 的区别
PGP 是商业软件,而 GPG 是开源软件,二者具有相同功能。
GnuPG 是一个混合加密软件程序,它使用常规对称密钥提高加密速度,使用公钥便于交换。通常使用一次性的收件人公钥用以加密会话。
对话密钥是客户端发送给服务端,还是服务端发送给客户端?
要回答这个问题,我们首先要知道,目前密钥交换的方式有两种 RSA 和 ECDHE,如百度的证书使用的是 RSA 算法,而 Google 使用的证书则是 ECC (Elliptic Curve Cryptography)算法。
它们各自的原理可以查看以下教程资料:
RSA 算法内容可以查看【李永乐老师 11 分钟讲 RSA 加密算法】、【基于欧拉函数的 RSA 算法加密原理是什么】或 【RSA 算法 – 基本原理篇】
ECC算法内容可查看【椭圆曲线加密与哈希函数是什么?】与【再谈 HTTPS】
了解了原理后,我们就可以回答对话密钥的生成问题了:
对于 RSA 算法来说,它是由浏览器生成对话密钥后,用服务器的公钥加密后发送给服务器,这样双方就得到了共享密钥。对于 ECC 算法来说,则是通过双方互相发送生成对话密钥所需参数,最终由各自生成对话密钥。
在 RSA 算法中,为什么是浏览器生成对话密钥,不能是服务器生成对话密钥吗?
答案是必须由浏览器生成。这是因为服务器的公钥是任何人都可以获取的,如果服务器用私钥生成对话密钥发送给浏览器,那这样其它用户也很容易获得这个对话密钥,这样就会导致通信内容的泄露,如果浏览器用公钥将自己生成的对话密钥发送给服务器,那就只能由这个公钥所对应的私钥解密(即使公钥本身也无法解密),从而保证了对话密钥的安全性。
SSL 握手过程是明文的,如果这个过程被监听,如何保障安全性?
如果在 RSA 算法的 HTTPS 握手中,我们监听并保存整个握手过程与经对话密钥加密的通信内容,即使我们无法立刻获取到通信的内容,但如果某天我们获取到了私钥,仍然可以使用这把私钥解密之前传送过的所有数据(即不支持前向安全性)。另一方面,RSA 的难点在于大数的质因数分解,虽然目前的经典计算机破解几乎不可能,但即将到来的量子计算机则可以在瞬间破解,因此 RSA 会有一些潜在的风险。
而 ECC 算法不仅 Key Size 比 RSA 小很多(256 bits vs 2048 bits),而且ECC 是 C/S 各有一套公私钥,其公钥又是通过私钥计算出的椭圆曲线中的某个点,通过交换各自的公钥来协商对话密钥,从而避免了 RSA 可能导致监听数据的泄露问题。
ECDHE 与 ECDSA 的定义:ECDHE 的全称是 Elliptic Curve Diffie–Hellman key Exchange 椭圆曲线迪非 - 赫尔曼密钥交换,它是对迪非 - 赫尔曼密钥交换算法的改进。ECDSA的全称是Elliptic Curve Digital Signature Algorithm 椭圆曲线数字签名算法,是通过椭圆曲线算法对证书进行数字签名。它们都是 ECC 算法。
相比 RSA 密钥交换,DH 由传递 Premaster Scret 变成了传递 DH 算法所需的 Parameter,然后双方各自算出 Premaster Secret。所以在建立 SSL 过程中,Client Key Exchange 是发送 Parameter,然后服务端根据所需参数计算出对称私钥。Change Cipher Spec 表明客户端通知服务端采用刚才协商的参数进行加密通信,服务端同样返回 Change Cipher Spec 表明已收到并同意协商密钥。
加密通信与数字签名是具有对称性的,即加密通信是公钥加密,私钥解密;数字签名则是私钥签名,公钥认证。
使用 HTTPS 会使我的网络通信隐私受到严格保护吗?
答案是否定的。因为在 HTTPS 握手前,会先进行 DNS 的明文查询,因此监控者仍可得知用户所访问的网站,但不清楚握手后与网站的通信内容,因此 GFW 经常通过 DNS 监听阻断连接。
未加密的 DNS 通信也导致了广告注入、域名劫持等诸多安全问题,因此,DNS 加密通信呼之欲出。目前,主要有 DNS over TLS(DoT)与 DNS over HTTPS(DoH)两种方式,DoT需要启用新端口,这可能使得现有防火墙阻止它,那么用户和应用程序可能会试图退回到未加密的DNS,从而可能允许攻击者强制用户使用不安全的版本。DoH 本质上是 HTTPS,因此可以复用 443 端口,目前的各大浏览器厂商正在大力推广 HTTPS,逐步废除 HTTP,另一方面,使用 HTTPS 意味着 HTTP 协议的改进也可以使 DoH 受益,这使得 HTTPS 成为安全传输DNS消息的最佳选择。
更多关于 DNS 加密的内容,请阅读Cloudflare博客文章DNS加密说明 - Cloudflare
参考资料
- 根证书 - 维基百科
- 公钥认证 - 维基百科
- 证书颁发机构 - 维基百科
- 比特币是什么? - 江卓尔的回答
- 图解 SSL/TLS 协议
- 好奇猫学院
- 关于启用 HTTPS 的一些经验分享(二)
- 谈谈 HTTP/2 的协议协商机制
- 三种解密 HTTPS 流量的方法介绍
- 再谈 HTTPS - 会编程的银猪
- RSA 的原理与实现
- 从零开始搭建一个 HTTPS 网站
- 为什么部署SSL证书后,还是提示不安全
- HTTP Strict Transport Security (HSTS) and NGINX
- Nginx 重定向次数过多
- Openssl Cookbook
- Understanding PKI for busy folks
- SSL Configuration Generator
- Security/Server Side TLS
- Certbo Docs
- certbot在各系统的命令
- 查询域名下的所有证书