当我们在浏览器的地址栏,敲下
https://www.example.com
到页面内容展示到我们面前的这个过程中,浏览器经历了什么?
一、嗅探 VS 加密
在网络链路的信息传输的过程中,如果通信链路中出现一个 hacker
,那么明文展示的通信内容就会被 hacker
嗅探到,甚至通信内容都会被篡改。
为了防止明文泄密,那么就需要对明文进行加密,使得中间人无法获取信息。
目前主要分类两类加密方式:
- 对称加密: 加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。
图示:
明文 <-> 密钥 <-> 密文
常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。
优点:加密速度快 - 非对称加密: 需要一对密钥(公钥和私钥)。任何人都可以拿到公钥进行明文加密,但是只有私钥持有者才能对密文进行解密。
图示:
明文 -> 公钥 -> 密文 -> 私钥 -> 明文
优点:安全性更好 (暴力破解需要时间太长)
二、认证
虽然加密可以避免明文直接暴露,但是中间人还是可以欺骗双方的。例如浏览器向服务器请求时,中间人给你他的公钥,伪装成服务器与你通信。
现实生活中,个人可以通过政府发布的身份证进行证明。同样在虚拟的网络中,由大家都信任的 CA 组织,会给每个人出证明(电子签名(digital signature),电子证书(digital certificate))。
CA 组织将其他人的信息和公钥信息,用私钥加密成密文(即电子签名),签署到证书上即为电子证书。其他人通过 CA 的公钥进行解密,即可证明对方身份。在浏览器中,能够决定其他人的证书是否有效的公钥就是 根证书。
虽然加密和认证能保证通信信息的保密性,但是却无法保证通信信息的完整性。 单向Hash函数可以把输入变成一个定长的输出串,其特点就是无法从这个输出还原回输入内容,并且不同的输入几乎不可能产生相同的输出,拥有很好的抗碰撞性。因此服务器只要将明文内容做一个Hash运算得到一个Hash值,并一起加密传递过去给客户端。Hacker即便篡改了内容,客户端解密之后发现拿到的内容以及对应计算出来的Hash值与传递过来的不一致,说明这个包的完整性被破坏了。
三、HTTPS三次握手
https的通信安全是建立在 SSL/TLS 协议上的。其基本过程为:
- 客户端向服务器端索要公钥并进行验证。
- 双方协议生成“对话密钥”。
- 双方通过“对话密钥”进行加密通信。
其中 1、2 两步又被称之为 “握手阶段”,涉及到四次通信,如图所示:
Client Hello
此时客户端向服务器发出加密通信的请求。同时客户端会提供自身信息,如:
- 支持的协议版本
- 生成
session ticket 1
用于之后“对话密钥”的随机数 - 支持的加密方法
- 支持的压缩方法
- 请求域名(非必要,针对一台主机存在多个网站,例如虚拟主机用户)
Server Hello
此时服务器收到客户端请求后,向客户端发起响应。回应内容有:
- 确认使用的加密通信的协议版本,如果客户端与服务器支持的版本不一致,服务器关闭加密通道。
- 服务器生成的随机数
session ticket 2
,用于之后“对话密钥” - 确认使用的加密方法
- 服务器证书
- 客服端证书(非必要,一般金融机构只允许认证客户端连入自己的网络时,会向正式客户提供USB密钥,里面就包含了一张客户端证书。)
认证阶段
客户端收到服务器的回应后,首先会验证服务器的证书。如果证书没有问题,客户端会从证书中获取服务器的公钥,同时向服务器发送信息。
- 一个用于服务器公钥加密的随机数
session ticket 3
(又称为pre-master key
),防止窃听。 - 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 握手通知结束,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。
有了这三个随机数,双方就可以利用事先商定的加密方法,各自生成本次会话所用的同一把“会话密钥”。
至于需要用到三个随机数的原因为增加随机性,具体可参考:ssl协议中的dh算法的pre-master-secret
内容传输阶段
服务器收到客户端的session ticket 3
后,计算生成本次会话所用的“会话密钥”。然后向客户端发送消息。
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。
- 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。
自此整个握手阶段完成。之后客户端和服务器进行加密通信阶段。即使用普通的http
协议传输用“会话密钥”加密后的内容。
上述过程中,Client Hello 和 Server Hello阶段均使用明文通信,只有协商密钥时,才使用非对称加密(非常消耗CPU)。通信阶段均采用对称加密。
四、整个过程
当按下回车的整个过程,我们可以理解为:
- 浏览器向服务器打招呼,同时提供随机数1和自身信息。
- 服务器向浏览器响应,提供随机数2和证书,确认加密方法。
- 浏览器对服务器回应的证书进行验证,如果通过则生成随机数3和会话密钥,并向服务器回应使用证书公钥加密的随机数3,否则断开连接。
- 服务器依据3个随机数和加密方法生成对应的会话密钥,结束整个SSL握手阶段。
- 浏览器和服务器进行通信,输出响应使用会话密钥加密的数据。
五、相关讨论
https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/70