浅谈 SSL&TLS 工作原理 - 转载

警告
本文最后更新于 2024-01-15,文中内容可能已过时。

浅谈 SSL&TLS 工作原理 - 转载

参考博客:浅谈 SSL/TLS 工作原理

为了保证网络通信的安全性,需要对网络上传递的数据进行加密。现在主流的加密方法就是 SSL (Secure Socket Layer),TLS (Transport Layer Security)。后者比前者要新一些,不过在很多场合还是用 SSL 指代 SSL 和 TLS。

先来回顾一下网络通信加密的发展过程,假设 A 和 B 之间要网络通信。

远古时代

远古时代自然是民风淳朴,路不拾遗,夜不闭户。A 要发数据给 B,根本不用担心窃听和篡改,直接发就好了。

上古时代

随着时代的发展,渐渐的有了一类人—C。C 不仅会监听 A 和 B 之间的网络数据,还会拦截 A 和 B 之间的数据,伪造之后再发给 A 或者 B,进而欺骗 A 和 B。C 就是中间人攻击(Man In The Middle Attack)。

为了应对 C 的攻击,A 和 B 开始对自己的数据进行加密。A 和 B 会使用一个共享的密钥,A 在发送数据之前,用这个密钥对数据加密。B 在收到数据之后,用这个密钥对数据解密。因为加密解密用的是同一个密钥,所以这里的加密算法称为对称加密算法

在 1981 年,DES(Data Encryption Standard)被提出,这是一种对称加密算法。DES 使用一个 56bit 的密钥,来完成数据的加解密。尽管 56bit 看起来有点短,但时间毕竟是在上古时代,56bit 已经够用了。就这样,网络数据的加密开始了。

因为采用了 DES,A 和 B 现在不用担心数据被 C 拦截了。因为就算 C 拦截了,也只能获取加密之后的数据,没有密钥就没有办法获取原始数据。

但是 A 和 B 之间又有了一个新的问题,他们需要一个共享的 56bit 密钥,并且这个密钥一定要保持私密,否则被 C 拿到了,就没有加密的意义了。首先 AB 不能通过网络来传递密钥,因为密钥确定以前,所有的网络通信都是不安全。如果通过网络传递密钥,密钥有可能被拦截。拦截了就没有加密的意义了。为了安全,A 和 B 只能先见一面,私下商量好密钥,这样 C 就没办法获取密钥。如果因为任何原因,之前的密钥泄露了,那么 AB 还得再见一面,重新商量一个密钥。

现在 A 和 B 之间,最私密的信息就是这个密钥了,只要保证密钥的安全,那么 AB 之间整个网络通信都是安全的。

中古时代

A 和 B 小心的保护着密钥,不让 C 知道。但是道高一尺,魔高一丈。随着技术的发展,计算机速度变得很快,快到可以通过暴力破解的方法来解密经过 DES 加密的信息。不就是 56bit 的密钥吗?C 找了一个好点的计算机,尝试每一个可能的值,这样总能找到一个密钥破解 A 和 B 之间的加密信息。倒不是说 DES 在提出时没有考虑过这种情况,只是在上古时代,计算机没这么快,破解 56bit 的密钥需要的时间非常长。但是现在是中古时代,可能只需要几天就可以破解 56bit 的密钥。

为了应对这个情况,新的协议被提出,例如 triple-DES(最长 168bit 的密钥),AES(最高 256bit 的密钥)。经过这些改进,至少在可以预见的未来,计算机是没有办法在有限的时间内,暴力破解这个长度的密钥。所以,在中古时代,将对称加密算法的密钥长度变长,来应对中间人攻击。但是 A 和 B 还是需要见面商量一个密钥。

现代

非对称加密

时间到了现代。网络通信变得十分发达,A 不只与 B 通信,还同时还跟其他 10000 个人进行网络通信。A 不可能每个人都跑去跟他们见个面,商量一个密钥。

所以一种新的加密算法被提出,这就是非对称加密算法。非对称加密使用两个密钥,一个是 public key,一个是 private key。通过一个特殊的数学算法,使得数据的加密和解密使用不同的密钥。因为用的是不同的密钥,所以称为非对称加密。非对称加密最著名的是 RSA 算法,这是以其发明者 Rivest, Shamir 和 Adleman 命名。非对称加密算法里面的 public key 和 private key 在数学上是相关的,这样才能用一个加密,用另一个解密。不过,尽管是相关的,但以现有的数学算法,又没有办法从一个密钥,算出另一个密钥。

非对称加密的好处在于,现在 A 可以保留 private key,通过网络传递 public key。这样,就算 public key 被 C 拦截了,因为没有 private key,C 还是没有办法完成信息的破解。既然不怕 C 知道 public key,那现在 A 和 B 不用再见面商量密钥,直接通过网络传递 public key 就行。

具体在使用中,A 和 B 都各有一个 public key 和一个 private key,这些 key 根据相应的算法已经生成好了。private key 只保留在各自的本地,public key 传给对方。A 要给 B 发送网络数据,那么 A 先使用自己的 private key(只有 A 知道)加密数据的 hash 值(感谢 @灵剑指正,评论区有说明),之后再用 B 的 public key 加密数据。之后,A 将加密的 hash 值和加密的数据再加一些其他的信息,发送给 B。B 收到了之后,先用自己的 private key(只有 B 知道)解密数据,本地运算一个 hash 值,之后用 A 的 public key 解密 hash 值,对比两个 hash 值,以检验数据的完整性。

在这个过程中,总共有 4 个密钥,分别是 A 的 public/private key,和 B 的 public/private key。

如果 B 的解密结果符合预期,那么至少可以证明,这个信息只有 B 能获取,因为 B 的 private key 参与了解密,而 B 的 private key 其他人都不知道。并且,这个信息是来自 A,而不是 C 伪造的,因为 A 的 public key 参与了解密。一切看起来似乎很美好。

关于非对称加密使用场景和相应的分析,请看《非对称加密》

非对称加密的安全隐患

但是在一切的最开始,A 和 B 要通过网络交换 public key。如果 C 在中间拦截了呢?假设有这种情况,C 拦截了 A 和 B 的 public key,又分别用自己的 public key 发给 A 和 B。A 和 B 并不知道,他们还以为这个 public key 来自对方。当 A 给 B 发消息时,A 先用自己的 private key 加密数据的 hash 值,之后用 C 传来的假的 public key 加密数据,再发出去。C 拦截到之后,先用 C 自己的 private key 解密数据,C 就获取了 A 的原始信息!之后,C 可以篡改数据内容,再用自己的 private key 加密数据的 hash 值,用之前拦截的 B 的 public key 加密数据,再发给 B。B 收到以后,先用自己的 private key 解密数据,再用 C 传来的假 public key 解密 hash 值,发现匹配。这样,B 收到了一条来自 C 的假的信息,但是 B 还以为信息来自于 A。中间人攻击仍然可能存在!

完了,一切都崩了,加密搞的这么复杂,居然还不能保证网络数据的安全。回顾一下,问题出就出在最开始通过网络交换 public key。看起来为了保证 public key 不被拦截,A 和 B 似乎还是要见一面,交换一下 public key。这一下就回到了上古时代。

不过,虽然 A 和 B 现在还是要见一面,但见面的实质已经变了。在上古时代,见面是为了商量一个密钥,密钥的内容很重要,不能让别人知道密钥的内容。而在现代,见面是为了确认 public key 的真实性,public key 的内容是可以公开的。

那如果有其他办法能保证 public key 的真实性,A 和 B 是可以不用见面交换 public key 的。

CA

现实中,通过 CA(Certificate Authority)来保证 public key 的真实性。CA 也是基于非对称加密算法来工作。有了 CA,B 会先把自己的 public key(和一些其他信息)交给 CA。CA 用自己的 private key 加密这些数据,加密完的数据称为 B 的数字证书。现在 B 要向 A 传递 public key,B 传递的是 CA 加密之后的数字证书。A 收到以后,会通过 CA 发布的 CA 证书(包含了 CA 的 public key),来解密 B 的数字证书,从而获得 B 的 public key。

关于 CA 签发证书的具体过程,请看《SSH 证书登录》

但是等等,A 怎么确保 CA 证书不被劫持。C 完全可以把一个假的 CA 证书发给 A,进而欺骗 A。CA 的大杀器就是,CA 把自己的 CA 证书集成在了浏览器和操作系统里面。A 拿到浏览器或者操作系统的时候,已经有了 CA 证书,没有必要通过网络获取,那自然也不存在劫持的问题。

现在 A 和 B 都有了 CA 认证的数字证书。在交换 public key 的阶段,直接交换彼此的数字证书就行。而中间人 C,还是可以拦截 A 和 B 的 public key,也可以用 CA 证书解密获得 A 和 B 的 public key。但是,C 没有办法伪造合法的证书。因为 C 不在 CA 体系里面,C 没有 CA 的 private key,所以 C 是没有办法伪造出一个可以通过 CA 认证的数字证书。如果不能通过 CA 认证,A 和 B 自然也不会相信这个伪造的证书。所以,采用 CA 认证以后,A 和 B 的 public key 的真实性得到了保证,A 和 B 可以通过网络交换 public key(实际是被 CA 加密之后的数字证书)。

除非有种情况,A 内置的 CA 证书被篡改了,例如 A 使用了盗版的系统,“优化”了的非官方浏览器,或者被病毒攻击了,那这个时候,A 有可能会认可非 CA 认证的数字证书,C 就有机会发起中间人攻击。所以,用正版至少是安全的。

实际使用

非对称加密算法比对称加密算法要复杂的多,处理起来也要慢得多。如果所有的网络数据都用非对称加密算法来加密,那效率会很低。所以在实际中,非对称加密只会用来传递一条信息,那就是用于对称加密的密钥(选长一点儿的,不那么容易被暴力破解,比如 168 位的 DES、256 位的 AES)。当用于对称加密的密钥确定了,A 和 B 还是通过对称加密算法进行网络通信。这样,既保证了网络通信的安全性,又不影响效率,A 和 B 也不用见面商量密钥了。

所以,在现代,A 和 B 之间要进行安全,省心的网络通信,需要经过以下几个步骤

  • 通过 CA 体系交换 public key

  • 通过非对称加密算法,交换用于对称加密的密钥

  • 通过对称加密算法,加密正常的网络通信

这基本就是 SSL/TLS 的工作过程了。

HTTPS

关于HTTPS的相关知识,请看《HTTPS》

HTTPS 全称是 HTTP over SSL,也就是通过 SSL/TLS 加密 HTTP 数据,这或许是 SSL 最广泛的应用。

前面提到了 CA 作为一个公证机构,能确保数字证书的真实性。但是在实际使用中,CA 认证一般是要收费的,普通人不会去做 CA 认证,进而获得属于自己的数字证书。更多的是,一些大的机构,例如银行,网店,金融机构,它们去获得自己的数字证书。那这种情况如何保证网络通信的安全呢?

这些机构获取到 CA 授予的数字证书之后,将数字证书加到自己的 web 服务器上。当用户要去访问它们的网页,例如 https://domain.com,会经过下图所示的步骤。

  • 用户向 web 服务器发起一个安全连接的请求

  • 服务器返回经过 CA 认证的数字证书,证书里面包含了服务器的 public key

  • 用户拿到数字证书,用自己浏览器内置的 CA 证书解密得到服务器的 public key

  • 用户用服务器的 public key 加密一个用于接下来的对称加密算法的密钥,传给 web 服务器

    • 因为只有服务器有 private key 可以解密,所以不用担心中间人拦截这个加密的密钥
  • 服务器拿到这个加密的密钥,解密获取密钥,再使用对称加密算法,和用户完成接下来的网络通信

现在用户知道自己访问的网站是正规的网站,否则用户浏览器会报错说不能用 CA 证书解析。服务器通过 CA 授予的数字证书自证了身份。但,这里的安全隐患在于,服务器怎么知道访问者就是真用户呢?之前介绍的双向认证是可以通过数字证书验明用户的正身,现在用户为了省钱没有数字证书。这种情况下一般是通过用户名密码来确认用户。所以,大家要保管好自己的密码。

0%