/* full handshake.
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
*/
ClientHello 包含随机数( client_rand )以及客户端所支持的加密/压缩算法列表
ServerHello 包含随机数( server_rand )以及选定的加密/压缩算法,以及session_id( 主要用于密钥恢复 ) ...
Certificate 包含服务器证书, ServerKeyExchange 包含服务器公钥,二者不会同时发送, 不发送Certificate包的时候安全性较低.
如果需要客户端验证, 则服务器将发送 CertificateRequest 请求客户端证书
最后跟随 ServerHelloDone 表示服务器响应结束
client随机生成 前主密文( pre_master_secret , tls1.0为48字节 ) 用服务器证书加密并包含在ClientKeyExchange包中被发送, 如果服务器请求客户端验证,则此时首先要发送客户端证书, 并对之前的协议数据签名, 签名包含在 CertificateVerify 中被发送, 通常在安全性要求很高的环境中(如网银等)才会要求双向验证. client发送 ChangeCipherSpec 表示密钥改变, 发送 Finished 表示客户端请求完成并包含对之前的协议数据的验证..
服务器用自己的私钥解密 前主密文 , 此时服务器和客户端用相同的数据( 包含 client_rand , server_rand , pre_master_secret ,其中只有 pre_master_secret 是加密的 ) 计算主密文( master_secret , tls1.0 也是48字节 ) , 最后双方用服务器在ServerHello
中选定算法计算加密参数( cipher_read , cipher_write , mac_read , mac_write , iv_read , iv_write ) ,服务器发送 ChangeCipherSpec 表示密钥改变, 发送 Finished 表示握手过程完成
密钥恢复就比较的简单, 如下图 ....
/* abbreviated handshake
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
*/
该模式如下图所示:
P0 P1 C0 C1
| | | |
| | |----| |--->...
IV--->XOR |--->XOR |--->... Key Dec | Dec
| | | | | | |
| | | | | | |
Key Enc | Enc | IV--->XOR |--->XOR
|-----| |-----| | |
| | | |
C0 C1 P1 P2
加密过程 解密过程
从这两个图中大家可以看到,CBC模式的加密首先也是将明文分成固定长度(64位)的块(P0,P1...),然后将前面一个加密块输出的密文与下一个要加密的明文块进行XOR(异或)操作计算,将计算结果再用密钥进行加密得到密文。第一明文块加密的时候,因为前面没有加密的密文,所以需要一个初始化向量(IV)。跟ECB方式不一样,通过连接关系,使得密文跟明文不再是一一对应的关系,破解起来更困难,而且克服了只要简单调换密文块可能达到目的的攻击。
但是该加密模式的缺点是不能实时解密,也就是说,必须等到每8个字节都接受到之后才能开始加密,否则就不能得到正确的结果。这在要求实时性比较高的时候就显得不合适了。