HTTPS引入SSL/TLS协议解决了HTTP不安全的问题:易被窃听,易被篡改,易被冒充.具体解决过程参考[HTTP面试题:HTTPS与HTTP:HTTPS解决了HTTP的哪些问题]
不同的密钥交换算法,TLS的握手过程也会发生一些变化.常见的密钥交换算法有RSA,ECDHE.
TLS第一次握手
客户端会发送一个[Client Hello]的消息,消息里面有随机数(用于之后会话密钥的生成),客户端支持的TLS版本号,支持的密码套件列表.
TLS第二次握手
服务器收到客户端的[Client Hello]消息,会确认消息中的TLS版本号是否支持,从密码套件列表中选出一个密码套件,并生成一个随机数,服务器会向客户端发送响应报文,报文中的消息包括生成的随机数(用于之后会话密钥的生成),选择的版本号和选择的密码套件以及用于验证自身身份的身份证书.
密码套件的基本形式:[密钥交换算法+签名算法+对称加密算法+摘要算法]
如:“Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256”,表示的含义是密钥交换算法和签名算法采用RSA,对称加密算法选择AES,生成的密钥长度为128位,摘要算法为SHA256.
这个随机数也是经过公钥加密发送的.这个公钥时客户端的公钥
具体过程:首先客户端是拥有服务器的公钥1的,然后随机生成一对公钥2和私钥2,然后客户端用公钥1加密公钥2发送给服务器,服务器用私钥1解密得到客户端的公钥2,随机数就是用公钥2加密发送的,客户端可以用私钥2解密得到随机数
客户端验证证书
客户端验证服务器的身份证书参考[HTTP面试题:HTTPS与HTTP:HTTPS如何建立连接,期间发生了哪些交互]
TLS第三次握手
客户端验证完证书后,会生成一个新的随机数(用于会话密钥的生成),并将该信息用RSA公钥加密发送给服务器,并将上述过程中的数据作个摘要(用会话密钥加密,以验证该会话密钥是否能够正常使用以及验证之前数据的完整性),用于服务器的校验以及告知服务器之后采用会话密钥通信
TLS第四次握手
服务器用RSA私钥解密并生成会话密钥,之后做相同的动作:将上述数据作摘要(同样用会话密钥加密)供客户端校验,并告知客户端之后采用会话密钥通信.
当服务器和客户端对会话密钥的验证无误后,之后就用会话密钥进行加解密数据传输
使用RSA算法生成会话密钥的最大问题是不支持前向保密.
客户端给服务器传递用公钥加密的随机数时,一旦服务器的私钥泄露,第三方就可以通过私钥去解密之前拦截的所有数据密文,为了解决这个缺陷引出了ECDHE算法(现在大多数网站使用的一种算法)
假设客户端和服务器各自随机生成一对公钥和私钥,分别标记为A,a,B,b.每一方的公钥A/B = G^a/b % P,其中G是底数,P是模数(通常是一个比较大的质数).当我们知道a/b,G,P时是很容易计算出A/B的,但反过来知道A/B,G,P是很难计算出a/b的.A,B是公开的,所以客户端和服务器交换公钥后,客户端通过Ba%P计算出会话密钥K,服务器通过Ab%P计算出会话密钥K,由于交换律二者计算的会话密钥是相等的
在DHE算法出现之前,还有一种DH算法叫做static DH算法.static DH算法是指客户端每次随机生成公钥而服务器的公钥是固定不变的.这样当交互海量数据后,黑客就可以通过这些数据中的有效信息暴力破解出服务器的私钥,进而可以计算出会话密钥.因此static DH算法不具备前向安全性.
DHE算法就是每次会话客户端和服务器随机生成一种公钥,这样即使黑客破解出这次通信的会话密钥,也不会影响其他的通信.通信过程之间是独立的,保证了前向安全.
由于DHE算法需要计算幂,所以需要计算大量的乘法.为了提升DHE算法的性能推出了ECDHE算法
ECDHE算法是利用ECC椭圆的特性可以用更少的计算量计算出公钥.
具体过程:
大致过程和RSA 握手过程是相似的.
不同的是第二次握手时,由于采用ECDHE密钥协商算法,所以服务器还需要选择一条椭圆曲线以及基点G,并通过生成随机数确定私钥,以及私钥和基点确定公钥,并将椭圆曲线利用RSA签名算法签名后发送给客户端.
第三次握手时客户端再验证了服务器的身份后,根据椭圆曲线和基点G生成自己的公钥,并结合服务器的公钥计算出会话密钥(x坐标),并将自身生成的公钥发送给服务器,服务器由此生成会话密钥
最终的会话密钥是由客户端生成的随机数+服务器生成的随机数+坐标x共同构成