■面试官求你了,别再问我HTTPS( 三 )


只有一组公钥私钥只能保证单程的加解密 , 那么如果我们准备两组公钥私钥呢 , 是不是可以解决这个问题?
来看下面这个过程:

  • 服务端有非对称加密的公钥 A1 , 私钥 A2 。
  • 客户端有非对称加密的公钥 B1 , 私钥 B2 。
  • 客户端向服务端发起请求 , 服务端将公钥 A1 返回给客户端 。
  • 浏览器收到公钥 A1 , 将自己保存的公钥 B1 发送给服务端 。
  • 之后浏览器所有向客户端发送的数据 , 使用公钥 B1 加密 , 客户端可以使用私钥 B2 解密 。
  • 客户端所有向服务端发送的数据 , 使用公钥 A1 加密 , 服务端可以使用私钥 A2 解密 。
此时 , 两条传输方向的数据都经过非对称加密 , 都能保证安全性 , 那么为什么不采用这种方案呢?
■面试官求你了,别再问我HTTPS
本文插图

最主要的原因是非对称加解密耗时要远大于对称加解密 , 对性能有很大损耗 , 大家的使用体验很差 。
所以 , 我们才最终选用了上文介绍到非对称加密+对称加密的方案 , 再复习一下:
  • 服务端有非对称加密的公钥 A1 , 私钥 A2 。
  • 客户端发起请求 , 服务端将公钥 A1 返回给客户端 。
  • 客户端随机生成一个对称加密的密钥 K , 用公钥 A1 加密后发送给服务端 。
  • 服务端收到密文后用自己的私钥 A2 解密 , 得到对称密钥 K , 此时完成了安全的对称密钥交换 , 解决了对称加密时密钥传输被人窃取的问题 。
  • 之后双方通信都使用密钥 K 进行对称加解密 。
看起来是一个非常完美的方案 , 兼顾了安全性和性能 , 但是 , 真的就安全了么?
CA 颁发机构
依然考虑中间人攻击的情况 , 非对称加密的算法都是公开的 , 所有人都可以自己生成一对公钥私钥 。
当服务端向客户端返回公钥 A1 的时候 , 中间人将其替换成自己的公钥 B1 传送给浏览器 。
而浏览器此时一无所知 , 傻乎乎地使用公钥 B1 加密了密钥 K 发送出去 , 又被中间人截获 。
中间人利用自己的私钥 B2 解密 , 得到密钥 K , 再使用服务端的公钥 A1 加密传送给服务端 , 完成了通信链路 , 而服务端和客户端毫无感知 。
■面试官求你了,别再问我HTTPS
本文插图

HTTPS 中间人
出现这一问题的核心原因是客户端无法确认收到的公钥是不是真的是服务端发来的 。 为了解决这个问题 , 互联网引入了一个公信机构 , 这就是 CA 。
服务端在使用 HTTPS 前 , 去经过认证的 CA 机构申请颁发一份数字证书 , 数字证书里包含有证书持有者、证书有效期、公钥等信息 。
服务端将证书发送给客户端 , 客户端校验证书身份和要访问的网站身份确实一致后再进行后续的加密操作 。
但是 , 如果中间人也聪明一点 , 只改动了证书中的公钥部分 , 客户端依然不能确认证书是否被篡改 , 这时我们就需要一些防伪技术了 。
前面说过 , 非对称加密中一般公钥用来加密 , 私钥用来解密 , 虽然私钥加密理论上可行 , 但由于数学上的设计这么做并不适合 , 那么私钥就只有解密这个功能了么?
私钥除了解密外的真正用途其实还有一个 , 就是数字签名 , 其实就是一种防伪技术 , 只要有人篡改了证书 , 那么数字签名必然校验失败 。
具体过程如下:
  • CA 机构拥有自己的一对公钥和私钥 。
  • CA 机构在颁发证书时对证书明文信息进行哈希 。
  • 将哈希值用私钥进行加签 , 得到数字签名 。
明文数据和数字签名组成证书 , 传递给客户端: