PRF(secret, label, seed) = P_<hash>(secret, label + seed) P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + HMAC_hash(secret, A(2) + seed) + HMAC_hash(secret, A(3) + seed) + ... // A(0) = seed // A(i) = HMAC_hash(secret, A(i-1))
服务器完成握手
服务收到请求后,首先校验客户端证书的合法性,并且验证客户端证书签名是否合法。根据服务器端证书私钥,解密 ClientKeyExchange,获得pre_master_secret, 用相同的PRF算法即可获取会话密钥,校验客户端 Finish 信息是否正确。如果正确,则服务器端与客户端完成密钥交换。 返回 change_cipher_spec, Finished 报文。
struct { enum { change_cipher_spec(1), (255) } type; // 固定值0x01 } ChangeCipherSpec; // 通知服务器后续报文为密文 struct { opaque verify_data[verify_data_length]; // 校验密文,算法PRF(master_secret, 'server finished', Hash(handshake_messages)) } Finished; // 密文信息,计算之前所有收到和发送的信息(handshake_messages)的摘要,加上`server finished`, 执行PRF算法
客户端会话开始
客户端校验服务器的Finished报文合法后,握手完成,后续用 master_secret 发送数据。