2.5.1 HTTPS 加密原理
本节,笔者以问题的形式,逐步解开 HTTPS 的面纱,帮助你彻底搞懂 HTTPS 加密原理。
1. 为什么需要加密
因为 HTTP 的内容是明文传输的,明文数据经过中间代理服务器、路由器、WIFI 热点、通信服务运营商节点时,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击(Man-in-the-middle attack,缩写:MITM)。所以我们才需要对信息进行加密,最容易理解的就是对称加密。
2. 什么是对称加密
加密和解密的过程可以使用一个密钥(Share key)作为参数,密钥必须保密,但加密和解密的过程可以公开。换句话说,只有知道密钥的人才能解密密文。常用的对称加密算法有 AES、ChaCha20、DES 等。因此,只要密钥不被中间人获取,两方通信的机密性就能得到保证。
图 2-11 对称加密示例
3. 只用对称加密是否可行
对称加密的核心在于如何保证密钥不被暴露。但由于 HTTP 通信模型是 1 对 N,如果所有人都共享同一个密钥,其实就相当于没有加密。如果由每个客户端随机生成一个密钥,并传输给服务端,那么就不存在共享密钥的问题了。
图 2-13 对称加密模式下密钥协商过程
但问题是客户端随机生成的密钥怎么传给服务端,同时不被别人知道。因为协商过程是明文的,密钥依然存在被中间人截获的可能性。此时,我们必须换一种思路,只使用对称加密就会陷入“无限套娃”的死胡同。这里我们就需要“非对称加密算法”。
4. 什么是非对称机密
简单说就是有两把密钥,通常一把叫做公钥(Public Key),可以向公众开放。另一把叫私钥或密钥(Private Key),私钥是必须保密的。用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。
图 2-11 非对称加密
非对称加密算法通常需要更多的计算资源,尤其在加密或解密大量数据时计算消耗更大。因此,我们使用计算效率更高的对称加密算法来加密 HTTP 内容,非对称加密算法来加密对称加密的密钥。请看下面的过程:
- 首先,客户端与服务端会进行协商,确定一个双方都支持的对称加密算法,例如 AES。
- 确认对称加密算法后,客户端会随机生成一个对称加密密钥 K。
- 客户端使用服务端的公钥加密密钥 K,并将密文传输给服务端。此时,只有服务端的私钥能够解密密钥 K。
如此,我们实现了”降低加/解密的耗时,同时又保证密钥传输的安全性“,达成既要安全又要效率的目标。但还有个问题仍需解决:“如何将服务器公钥传输给客户端呢?”。
5. 公钥仍有被劫持的可能性
如果服务端直接将公钥发送给浏览器,仍然无法避免中间被截获的风险。请看下面的过程:
- 浏览器向网站服务器请求,服务器把公钥 A 明文给传输浏览器。
- 中间人劫持到公钥 A,保存下来,把数据包中的公钥 A 替换成自己伪造的公钥 B(它当然也拥有公钥 B 对应的私钥 B)。
- 浏览器生成一个用于对称加密的密钥 X,用公钥 B(浏览器无法得知公钥被替换了)加密后传给服务器。
- 中间人劫持后用私钥 B 解密得到密钥 X,或者别的什么操作,再用公钥 A 加密后传给服务器。
- 服务器拿到后用私钥 A 解密得到密钥 X。
图 2-14 公钥存在被截获的可能性
这样在双方都不会发现异常的情况下,中间人通过一套“狸猫换太子”的操作,掉包了服务器传来的公钥,进而得到了密钥 X。
上述问题的根本原因是,浏览器无法确认收到的公钥是不是网站自己的。因为公钥本身是明文传输的,难道还得对公钥的传输进行加密?
6. 证明浏览器收到的公钥一定是该网站的公钥
其实所有证明的源头都是一条或多条不证自明的“公理”,由它推导出一切。比如现实生活中,若想证明某身份证号一定是小明的,可以看他身份证,而身份证是由政府作证的,这里的“公理”就是“政府机构可信”,这也是社会正常运作的前提。
那能不能类似地有个机构充当互联网世界的“公理”呢?让它作为一切证明的源头,给网站颁发一个“身份证”?它就是 CA 机构(CA,Certificate Authority,证书认证机构),它是如今互联网世界正常运作的前提,而 CA 机构颁发的“身份证”就是数字证书。
7. 什么是数字证书
网站在使用 HTTPS 前,需要向 CA 机构申领一份数字证书,数字证书里含有证书持有者、域名、公钥、过期时间等信息。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了。
数字证书就如身份证,证明“该公钥对应该网站”。而这里又有一个显而易见的问题:“证书本身的传输过程中,如何防止被篡改?”,即如何证明证书本身的真实性。
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名。请看数字签名的制作过程:
- CA 机构拥有非对称加密的私钥和公钥。
- CA 机构对证书明文数据T进行hash。
- 对 hash 后的值用私钥加密,得到数字签名 S。
明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。
8. 中间人有可能篡改数字证书么
假设中间人篡改了证书的原文,由于他没有 CA 机构的私钥,所以无法得到此时加密后签名,无法相应地篡改签名。浏览器收到该证书后会发现原文和签名解密后的值不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
既然不可能篡改,那整个证书被掉包呢?假设有另一个网站 B 也拿到了 CA 机构认证的证书,它想劫持网站 A 的信息。于是它成为中间人拦截到了 A 传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到 B 的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?
其实这并不会发生,因为证书里包含了网站 A 的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。
9. 怎么证明 CA 机构的公钥是可信的?
让我们回想一下数字证书到底是干啥的?没错,为了证明某公钥是可信的,即“该公钥是否对应该网站”,那 CA 机构的公钥是否也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中会有 CA 机构的根证书,这样就可以拿到它对应的可信公钥了。
实际上证书之间的认证也可以不止一层,可以 A 信任 B,B 信任 C。以此类推,我们把它叫做信任链或数字证书链,也就是一连串的数字证书。由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。
另外,不知你们是否遇到过网站访问不了、提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书。从整个流程来看,HTTPS 安全性的关键在于根证书是否被篡改。如果根证书被篡改,那么信息传递也就不再是‘绝对’安全的。
最后,总结 HTTPS 的通信加密逻辑,如图 2-16 所示。服务端向 CA 机构申请证书,并在 TLS 握手阶段将证书发送给客户端,客户端校验数字证书合法性。
图 2-16 HTTPS 通信流程
接下来,服务器为每个客户端维护一个 session ID 。浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的 session ID 下,之后浏览器每次请求都会携带 session ID,服务器会根据 session ID 找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了!