https学习笔记
一、SSL/TLS握手流程
SSL/TLS握手流程图,摘自rfc5246
Client | Server |
---|---|
1 Client Hello | |
2 Server Hello 3 certificate 4 (server_key_exchange) 5 (certificate_request) 6 server_hello_done |
|
7 (certificate) 8 client_key_exchange 9 (certificate_verify) 10 change_cypher_spec - - - -finished- - - - |
|
11 change_cypher_spec - - - -finished- - - - |
括号中的步骤是可选的。
如果是单向认证,那么5、7、9是不需要的。
4 server_key_exchange这一步只有在选择了某些密钥交换算法(例如DH算法)的时候才需要
二、基于RSA交换算法的握手流程
此文只涉及单向认证,不涉及双向认证。另外,此文中涉及的服务器证书是RSA签名证书,没有涉及ECDSA签名证书
1、tcp握手
客户端向服务器的443端口发起tcp建连请求
2、SSL/TLS握手
tcp三次握手完成之后,开始SSL/TLS握手
2.1、客户端发送Client Hello
客户端发到服务器的Client Hello
报文中会携带:
- 客户端能够支持的的SSL/TLS最高版本号
- 客户端支持的Cipher Suites(密码套件)列表
- 客户端生成的32字节随机数(Client random)
在使用wireshark抓包时,是对
curl -vo /dev/null -k --ciphers rsa_aes_128_cbc_sha_256 https://www.xxx.com
这一访问进行的抓取,也因此,client hello中的cipher suites列表只有一个TLS_RSA_WITH_AES_128_CBC_SHA256
2.2、服务器回应Server Hello
如果服务器支持SSL/TLS,收到Client Hello后会回应Server Hello
,回应包含:
- 确认要使用的SSL/TLS版本号
- 服务器生成的随机数(Server random)
- Session ID
- 确认要使用的Cipher Suites
2.3、服务器回应certificate
2.4、服务器回应Server Hello Done
2.5、客户端验证数字证书
客户端收到certificate报文中包含的certificates(数字证书),开始对其进行验证
- 在证书链中依次找到服务器证书、中间CA证书1、[<中间CA证书2>…<中间CA证书n>]
- 根据最后一级
中间CA证书n
内容中的issuer
在操作系统或浏览器中找到已内置的根CA证书 - 使用根CA证书中的
Public Key(公钥)
解密下一级中间CA证书n
中的数字签名,得到hash值1
,并使用中间CA证书n
中标明的hash算法对中间CA证书n
中的相关明文内容进行hash计算,得出hash值2
,如果hash值1
等于hash值2
,则说明中间CA证书n
是完整和合法的,没有被冒充 - 使用
中间CA证书n
中的公钥解密下一级中间CA证书n-1
中的数字签名,进行上面相同的验证过程,以此类推。 - 使用
中间CA证书1
中的RSA公钥解密服务器证书
中的数字签名,进行上面相同的验证过程
以上任何一个环节验证失败,客户端都会提示失败
2.6、客户端发送Client Key Exchange
客户端对证书验证证通过后,生成一个新的48字节的随机数(premaster secret),使用服务器证书
中的public key
(公钥)对Premaster Secret
进行加密生成Encrypted Premaster Secret
,然后包含进Client Key Exchange
中发给服务器。(这个加密和发送过程其实就是在按照前面约定好的RSA密钥交换算法在进行)。
2.7、客户端发送Change Cipher Spec
客户端通知服务端,后续的报文将会被加密
2.8、客户端发送Encrypted Handshake Message
客户端结合前面的premaster secret和两个随机数client random和server random,使用前面协商好的算法(伪随机函数PRF),生成对话主密钥master secret
,然后将之前(准备发送Encrypted handshake message前)所有的握手数据(包括接受、发送)进行摘要计算,并使用master secret进行对称加密,发给服务端。
服务端接收后,服务端用同样的方式计算出已交互的握手消息的摘要,与用主密钥解密后的消息进行对比,一致的话,说明两端生成的主密钥一致,且从客户端收到过的握手消息没有被篡改过。
2.9、服务端发送Change Cipher Spec
服务端通知客户端,后续的报文将会被加密
2.10、服务端发送Encrypted Handshake Message
服务器收到客户端发送的Client Key Exchange,从中取到Encrypted Premaster Secret
,使用自身拥有的私钥对其进行解密,得到premaster secret
,然后结合前面的两个随机数client random和server random,使用协商好的算法(伪随机函数PRF),生成对话主密钥master secret,对握手信息进行摘要计算然后使用master secret加密后发给客户端
客户端接收后,使用主密钥解密,消息摘要认证通过后,SSL握手完成。