HTTP相关内容(二) | 青训营
HTTP1.1 由于是明文传输,所以在HTTP和TCP之间多加一层SSL/TLS安全协议。来保证安全性。上文说到该协议是通过信息加密、校验机制、身份证书来解决问题的。
那么在开始HTTP通讯之前,要先经过TLS握手,也就是TCP三次握手之后,在来个TLS四次握手,才建立安全连接。而TLS握手会基于不同的密钥交换算法,所有也不尽相同。
传统的基于RSA算法的握手:
step1、客户端发送 “Client Hello”信息。包含客户端使用的TLS版本号,支持的密码套件,以及随机数(服务端会保留该数字用于生成密钥)
step2、服务端收到消息后,确认是否支持TLS版本,选择一个密码套件也生成一个随机数,并返回“Server Hello”信息、并且也会发送“Server Certificate”信息,这里面有自己的数字证书。随后发送“Server Hello Done”,标志本次传输结束。
step3、客户端验证完后,生成新的随机数,并使用服务器公钥加密。通过“Client Key Exchange”信息发给服务端。此时两边都有三个随机数,用这三个随机数,生成会话密钥,由于后续的HTTP数据加密。有了密钥,客户端会发送“Change Cipher Spec”,说我以后的话可是要加密了。还会把之前发送的消息摘要加密一下,让服务端验证。
step4、服务端收到消息验证没问题,也会发送“Change Cipher Spec”和之前信息摘要的加密信息。若客户端验证没问题,就完成了TLS握手过程
RSA算法有一个隐患,就是一旦服务端私钥泄漏(小概率),加密通讯就不能完成,或者没有加密效果了,因为随机数交换是明文的。
这就引出第二个加密算法:ECDHE算法
该算法利用了椭圆曲线特性,双方先规定好使用哪一种椭圆曲线和曲线基点G,这些是公开的。随后双方个生成一个随机数所谓私钥,与G相乘得到公钥(Q = G * RandNum)。此时客户端公私钥分别为 Q1,RandNum1。服务端公私钥分别为 Q2,RandNum2。双非各自交换公钥,客户端计算点(x1,y1)= Q2 * RandNum1。服务端计算点(x2,y2)= Q1 * RandNum2。由于椭圆曲线特征,两边点的x坐标是一样的,这样就有了一个共有的密钥,用它加密通话。随后也进行四次TLS握手。
与之前不同的是,第二次握手时,服务端选择的是 ECDHE算法,他会挑一个椭圆曲线,生成随机数作为私钥,并计算出公钥并给到客户端。之前提到的x坐标实际也不是最终的会话密钥,会把它和之前的三个随机数共同生成随机数,主打的就是随机和安全。