最近在看公司的SSL协议实现,现将其流程总结如下:
步骤解释如下:
1. client -> ClientHello -> server。
(1). ClientHello 消息体 = Client.Version (客户端协议版本)+ClientHello.Timestamp( 客户端时间戳) +ClientHello.Random (客户端随机数)+会话sessionID +CipherSpecs (client支持的算法集)+Certificate.SerialNumber( 服务器证书序列号)。
2. server -> ServerHello -> client。
(1). server创建会话session ID ,缓存ClientHello.Timestamp 与ClientHello.Random ,根据CipherSpecs 的支持加密集合和server 自己支持的加密集合选择本次会话的加密算法集CipherSuite 。
(2).ServerHello 消息体 = Server.Version( 服务器协议版本号) +ServerHello.Timestamp (服务器时间戳)+ServerHello.Random( 服务器随机数) +sessionID (服务器会话)+CipherSuite (本次会话指定的加密算法)+ServerCertificate( 服务器公钥证书) 。
(3).如要验证client身份,发送CertificateRequest 。
3. client -> ClientKeyExchange -> server
(1). client缓存ServerRNS(服务器随机数) 、ServerCertificate(服务器证书) +sessionID (服务器会话)+CipherSuite (本次会话指定的加密算法集) ,生成客户端随机数(ClientRNC)。
(2). 用 客户端协议版本号+ 随机数 生成客户端预主密钥premaster secret [PMS ], 使用 服务器证书公钥 加密 (PMS + ServerRNC } 。
(3). 如果服务器发送CertificateRequest 按顺序连接,使用客户端的私钥签名,在CertificateVerify 中发送这个签名。
(4). 发送ChangeCipherSpec 声明切换到加密信道传输 。
(5). 用(PMS,ServerRNS,ClientRNC)计算客户端主密钥master secret[MS ] ,生用MS成信道验证的Finished 消息。将Finished 之前发出的和接收到消息(不包括Finished 本身)的二进制数据,按照顺序连接后,使用MS 做PRF 签名。
4. server -> ChangeCipherSpec -> client
(1). server使用私钥解密并取出{PMS ,RNC} 。使用PMS 、RNC 、RNS 计算MS 。
(2). 生成服务器的预主密钥premaster secret2 [PMS2 ] 。使用PMS2 、RNC 、RNS 生成服务器主密钥master secret2 [MS2 ] ,在会话中保存MS2 作为传输密钥。
(3). 如果有ClientCertificate ,验证相关信息。验证客户端的Finished 信息。如果错误,返回标准失败信息。
(4). 生成服务器的Finished ,将Finished 之前发出的和接收到消息(不包括Finished 本身)的二进制数据,按照顺序连接后,使用MS 做PRF 签名。
(5). 回传客户端消息 = ServerKeyExchange[用MS对称加密(PMS2)] +确认加密算法集ChangeCipherSpec +发送自己的Finished 消息。
5. client收到server信息后:
(1). 验证服务器的Finished 消息。如失败,切断当前连接。
(2). 根据协商好的对称加密算法,使用本地保存的MS 解ServerKeyExchange 。使用PMS2 、RNC 、RNS 生成MS2 作为session 密钥。在缓存中保存RNS2 。