诞生

随着 web 发展,信息越来越多,拥有的功能也越来越多,数据安全问题越来越被重视。1994 年底网景,在 TCP/IP 协议基础上创建了一个额外的加密传输层:SSL;随着 web 应用程序的使用越来越广,可访问个人信息越来越多,加密需求高涨,SSL 加入了 http 中,https 应运而生。

原理

对称加密

对称机密,也即浏览器和服务器都有用一个加密的密钥,对数据进行加密和解密。这是最简单最容易想到的方法似乎逻辑上也能行得通过,因为只有服务器和浏览器知道这个密钥其他人除了破解就不可能解密拿到数据。但是问题是怎么保证只有服务器和浏览器拥有这个密钥。浏览器第一次向服务器发送请求,服务器此时还没密钥,服务器只能通过 http 响应传给浏览器密钥,而这里可以被劫持(http 传输肯定需要经过一些路由,电脑节点)。对称加密方式的缺点在于无法保证密钥只有通信的双方拥有。

非对称加密

非对称加密,分为公钥和私钥,私钥是拥有者自己的不会进行传递,公钥是给通信对方的(可以说是公开的),数据用公钥加密后能用私钥解密,私钥加密的能用公钥解密。浏览器发起第一次 http 请求,服务器响应给浏览器公钥(公钥仍有可能被泄露),往后浏览器发送给服务器的数据都会用公钥加密,那么能解密的只有服务器的私钥,而私钥没有进行过传输,那么就不存泄露的危险,所以浏览器到服务器的数据安全得到保证了。但是由服务器发送给浏览器的数据因为公钥可能会泄露,所以服务器发送到浏览器的数据安全还是存在问题的

两层加密方式

​ 两层加密方式,非对称加密保证了双向数据的单向安全,那么用两对公私钥就可以保证了双向的安全:浏览器第一次发送请求,服务器响应发送服务器的公钥 A 给浏览器,浏览器得到了公钥 A,第一次交互保证了浏览器到服务器的数据安全。然后浏览器用得到的公钥 A 加密自己的公钥 B 发送给服务器,服务器用私钥 A 解密得到了浏览器公钥——公钥 B,往后服务器发送给浏览器的数据都用公钥 B 加密,这些数据只能由私钥 B 解密,而私钥 B 只存在浏览器中没经过发送,所以服务器到浏览器的数据安全也得到了保证。这样服务器和浏览器的数据交互似乎就安全了。

​ 两层加密方式里面,考虑到非对称加密的加密和解密算法过于复杂耗时,第二层其实可以用对称加密代替,因为有了第一层非对称加密保证的浏览器到服务数据安全,那么第二层的对称加密密钥传输安全是可以保证的,所以第二层用更简单的对称加密替换原来的非对称加密,这样的性能更好:浏览器第一次发送请求,服务器响应发送服务器的公钥 A 给浏览器,浏览器得到了公钥 A,第一次交互保证了浏览器到服务器的数据安全。然后浏览器用得到的公钥 A 加密一份对称加密的密钥发送给服务器,服务器用私钥 A 解密得到了对称加密的密钥。这样服务器和浏览器都有对称加密的密钥,而且这个密钥不可能在 http 传输中泄露,那么往后数据交互可以都用对称加密密钥加密,到达对方后解密即可。

这里的逻辑:非对称加密交互一次=》确定单向传输的安全=》用这个传输对称加密密钥=》对称加密密钥不会泄露=》往后都用对称加密加解密。

中间人攻击和证书

​ 所谓道高一尺,魔高一丈。心思缜密的黑客还是发现了漏洞:在浏览器向服务器发起第一次请求中,服务器需要明文给浏览器公钥 A,黑客利用这一点,http 经过其 ip 时,把这个公钥 A 保存下来,而且把传输的公钥 A 改成自己一个公钥 B,这样到达浏览器的就是黑客的公钥 B,而浏览器无法察觉只得以为这个公钥 B 就是服务的公钥。然后浏览器按上面所写的又发起了第二层,公钥 B 加密的对称加密密钥,当数据经过黑客的 ip 时,直接用直接的私钥 B 解开的加密,得到了对称加密密钥(芜湖~),然后用服务器给的公钥 A 加密这个对称加密密钥再发送给服务器。服务器接收到解密得到对称加密密钥,也无法发现泄露,往后使用了这个对称密钥加解密。。。这种数据在中间被替换了的攻击就是大名鼎鼎的——中间人攻击

  • 中间人攻击可行的原因在于,浏览器无法确定第一次接收的公钥是否来自请求的服务器,也即公钥来源是“身份问题”。身份问题的解决在现实中就是身份证,身份证是由公信力最高的政府颁发(!?),这样你是 a 还是 b,给出身份证就行了。https 也基本是这样,一个有公信力的机构——”CA 机构“颁发数字证书,证书里面有证书持有者证书持有者的公钥

    • 证书的制作:

      首先 CA 会有自己的一对公私钥,在一开始证书明文的信息会被进行 hash,hash 后再用 CA 自己的私钥进行加密,这样得到的一段数据称数字签名,然后证书明文信息和对应的数字签名就是数字证书了。

    • 证书具体的使用:

      服务器购买了证书,在浏览器第一次请求时,服务器会把证书发给浏览器,浏览器接收后把证书的明文部分用其中的 hash 函数进行 hash,得到一段 hash 值 C1,然后浏览器自己会存储一些可信的 CA 机构的公钥,用这个公钥去对接收到的证书的数字签名进行解密,也会得到一段 hash 值 C2,对比 C1 和 C2 是否相等,若相等则说明证书信息正确没被篡改,证书明文中的证书持有者(也即浏览器请求的服务器)公钥是正确的。至此公钥的身份问题就解决了,再进行前面提到的两层加密方式即可。

    • 证书为什么不能被篡改?

      由于数字签名是用 CA 的私钥进行加密的,私钥只有 CA 自己有,任何攻击者都无法获取 CA 的私钥。所以如果攻击者改变了证书明文部分的公钥那么他也需要改变证书里面的数字签名(不然对比明文 hash 和数字签名解密后 hash 不等,会被识破篡改了),但因为攻击者无法获取 CA 的私钥,他想再把篡改后的明文信息 hash 后进行加密就会失败(用 CA 的公钥加密,浏览器用的公钥无法解密),所以数字签名是无法被篡改的或者说篡改后一定会被识破,这里的关键就 CA 的私钥。所以如果 CA 泄露了私钥那么公信力就会丢失,证书也就不可信了,证书讨论是建立在 CA 私钥不可泄露的前提下的。

      攻击者能不能给自己的证书浏览器?其实证书的明文部分里有证书的持有者(域名等)这一项,浏览器直接查看证书的持有者是否是自己请求的服务器(域名)就行了。

总结

也即 https 是利用了非对称加密+对称加密+数字证书构成加密过程的

https建立的过程(HTTPS handshake)

  • 基于TCP连接建立成功后开始
  • 在TCP三次握手的最后一次,客户端发送ACK确认建立连接,会顺带上一个ClientHello,包含着TLS的版本,支持的密码套件,以及一串客户端生成的随机数“客户端随机数”ClientRandom
  • 接着服务端回复ServerHello,SSL证书,服务器选择的密码套件,以及一串服务器生成的随机数“服务端随机数”ServerRandom
  • 客户端验证接受的证书(详细查看https章),获得服务端的公钥,此时客户端在生成一个随机数,利用三个随机组成对称密钥,往后使用这个密钥加密通话;当然,此时服务端还不知道最后一个随机数,所以客户端还需要再通过得到的公钥加密这个随机数发给服务端;
  • 这样,利用公钥加密发送个私钥的通道是安全的(非对称加密,保证的单向通道安全),可以保证第三个随机数不会被泄露,也即可以保证密钥不会被泄露,往后客户端和服务端通讯都用这个密钥(对称密钥即可);

补充一些加密知识

  • md5,一种hash算法,早期美国发明的,也是用来加密的。但是注意,这种加密是不可逆的(加密后解密不了的},所以根本就不能用来做加密解密的工作,更多的是用于验证手段。(不过现在已经能被破解了。。。)
    • 比如文件验证(文件指纹),不同时间的两个文件md5加密后对比一样则没有修改是同一个文件,否则就是被修改过/不是统一个文件;
    • 如密码,用户注册的时候,把密码md5加密后存储到数据库,下次用户登录输入密码,可以再次通过md5加密,结果与数据库对比,相同则密码正确,不同则不正确,这样系统开发者也不能知道密码(良心系统),也可以减低数据库数据泄露(sql注入)危害。
  • sha-256:和md5一样也是一种hash算法,hash都是不可逆的(hash本身来说就是一对多,即解密答案有多个,而这怎么算解密呢),md5和sha-1/2/3等都是不同数据加密得到不同的hash值概率很高很高,所以hash后的值可以作为唯一标识。

此外:可能还涉及了另外一些名词,证书链

参考:

彻底搞懂 HTTPS 的加密机制

最后更新: 2021年07月15日 23:52

原始链接: https://idkhts.github.io/2021/01/19/https/