HTTP

密钥协商的步骤

  1. 客户端连上服务端
  2. 服务端发送 CA 证书给客户端
  3. 客户端验证该证书的可靠性
  4. 客户端从 CA 证书中取出公钥
  5. 客户端生成一个随机密钥 k,并用这个公钥加密得到 k'
  6. 客户端把 k' 发送给服务端
  7. 服务端收到 k' 后用自己的私钥解密得到 k
  8. 此时双方都得到了密钥 k,协商完成。

基于 CA 证书进行密钥交换

  1. 网站方面首先要花一笔银子,在某个 CA 那里购买一个数字证书。

    该证书通常会对应几个文件:其中一个文件包含公钥,还有一个文件包含私钥。网站方面必须在 Web 服务器上部署这两个文件。

    所谓的“公钥”,顾名思义就是可以公开的 key;而所谓的“私钥”就是私密的 key。

    其实前面已经说过了,这里再唠叨一下: “非对称加密算法”从数学上确保了——即使你知道某个公钥,也很难(不是不可能,是很难)根据此公钥推导出对应的私钥。

    这是“一次性”的准备工作。

  2. 当浏览器访问该网站,Web 服务器首先把包含公钥的证书发送给浏览器。

  3. 浏览器验证网站发过来的证书。如果发现其中有诈,浏览器会提示“CA 证书安全警告”。

    由于有了这一步,就大大降低了(注意:是“大大降低”,而不是“彻底消除”)前面提到的“中间人攻击”的风险。

    为啥浏览器能发现 CA 证书是否有诈? 因为正经的 CA 证书,都是来自某个权威的 CA。如果某个 CA 足够权威,那么主流的操作系统(或浏览器)会内置该 CA 的“根证书”。 (比如 Windows 中就内置了几十个权威 CA 的根证书)

    因此,浏览器就可以利用系统内置的根证书,来判断网站发过来的 CA 证书是不是某个 CA 颁发的。 (关于“根证书”和“证书信任链”的概念,请参见之前的教程《数字证书及CA的扫盲介绍》)

  4. 如果网站发过来的 CA 证书没有问题,那么浏览器就从该 CA 证书中提取出“公钥”。

    然后浏览器随机生成一个“对称加密的密钥”(以下称为 k)。用 CA 证书的公钥加密 k,得到密文 k'

    浏览器把 k' 发送给网站。

  5. 网站收到浏览器发过来的 k',用服务器上的私钥进行解密,得到 k。

至此,浏览器和网站都拥有 k,“密钥交换”大功告成啦。