HTTPS 中的密码技术

HTTP 是我们平时浏览网页时候使用的一种协议。HTTP 协议传输的数据都是明文未加密的,因此使用 HTTP 协议传输隐私信息非常不安全。
为了保证这些隐私数据能加密传输,网景公司设计了 SSL(Secure Sockets Layer)协议用于对 HTTP 协议传输的数据进行加密,从而就诞生了 HTTPS。
其目前的版本是 3.0,被 IETF 定义在 RFC 6101 中,之后 IETF 对 SSL 3.0 进行了升级,于是出现了 TLS(Transport Layer Security)。
SSL/TLS 中综合运用了对称密码、消息认证码、公钥密码、数字签名、伪随机数生成器等密码技术。

简单来说 HTTPS 就是在应用层(HTTP)和传输层(TCP)中加了一层 SSL/TLS。

至于是如何进行数据加密的,先来看看原来的传输协议面临的问题:

  1. 传输的内容在发送过程中不能被篡改;
  2. 传输的内容在发送过程中不能被窃听;
  3. 确认通信对方是否为真正的要传输的对象。

防止篡改

要防止被篡改,可以使用 hash 函数来实现。比如 SHA-256,MD5,又或者 HMAC。
发送者与接受者预先共享一串密钥,加上任意长度的消息进行 Hash 计算。
通过这种方式来确认消息的完整性,这种方式称为消息认证码。

但是 Hash 函数有个问题,无法防止重放攻击。
比如小明用手机向你转账 1 万,这时候你拦截了请求,并重复发送。
虽然你看不懂请求的内容,但是对于银行来说这是合法的请求。
这解决这种方法,接收者需要先向发送者发送一个一次性的随机数,一般称为 nonce。
发送者在消息中包含这个 nonce,并计算 hash 值。

但如何事先将这共享密钥发送出去呢?

防止窃听

要防止窃听,可以使用对称密码。使用随机数生成器来生成密钥。然后使用公钥来发送给通信对象。
一般情况下是服务端下发公钥给客户端,客户端使用公钥对消息内容进行加密,在返回给服务端。
服务端用自己的私钥进行解密。这就是所谓的 RSA 非对称加密。

RSA 性能非常低,原因在于寻找大素数、大数计算、数据分割需要耗费很多的 CPU 周期,所以一般的 HTTPS 连接只在第一次握手时使用非对称加密,通过握手交换对称加密密钥,在之后的通信走对称加密(AES)。

但是对于客户端,如何确定这公钥的来源是正确的呢?这就涉及常见的中间人攻击。

对象认证

要确认这个公钥的合法性,我们需要一个第三方机构来进行认证。
第三方先对公钥加上数字签名,也就是生成证书。

那什么是数字签名?
数字签名相当于公钥密码的逆过程。先用私钥对消息内容进行加密生成签名,公钥揭秘来验证签名。

总结

服务端下发包含公钥的证书给客户端,客户端向第三方来验证证书中的数字签名。
如果证书合法,客户端产生一段随机数,这个随机数就作为通信的密钥(对称密钥),用公钥加密这段随机数,然后发送到服务器
服务器用密钥解密获取对称密钥,然后,双方就已对称密钥进行加密解密通信了。
这样我们所说的三个问题就一一解决了。实际中的 HTTPS 过程会更琐碎一些。

最后

最后有人可能想问,如何确定第三方认证机构的合法性?这个问题貌似又回到了对象认证的起点。
如果能确认公钥的合法性,确实不需要第三方认证机构。比如 12306。
但如果不能十分确认公钥的合法性,有个比较相信的第三方认证机构进行确认的情况下,可信度是不是更高?

参考资料:
HTTPS那些事(一)HTTPS原理