josephzy 发表于 2013-1-27 06:24:28

[求助]建立TLS通道最后一步Finished消息加解密

在做TLS通道最后一步:Client和Server交换Finished消息时,遇到几个难题。先说说Finished消息的内容及由来:

步骤前提及已有资源:

1.         客户端和服务端协商出一套加密算法,包括以下内容:

a)         Authentication: RSA

b)         Encrypteion: RC4_128

c)         MAC: MD5

2.         Master_Secret,和由Master_Secret计算得到的密钥参数:

a)         Client_Write_Key

b)         Client_Write_MAC_Secret

c)         Server_Write_Key

d)         Server_Write_MAC_Secret

3.         PRF:哈希函数,在TLS中定这样的PRF算法:

PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);

其中S1、S2为secret拆分开来的两段字符串。

4.         RFC2246定义Finished报文格式:

struct {
opaque verify_data;

} Finished;

客户端:

1.         客户端将之前所有握手交互产生的数据做PRF,产生一个12字符的摘要赋值给Finished报文的verify_data属性:
verify_data = PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages))
其中handshake_messages包括从Client_Hello开始到Client_Finished之前(不包含Client_Finished)的所有握手消息。
Finished_label = “client finished”;

2.         客户端组装Client_Finished消息;

3.         利用Client_Write_Key将Finished消息用RC4_128算法加密,生成Encrypted_Handshake_Message后发送。

服务端:

1.         检验客户端发送的Client_Finished消息:

a)         利用Client_Write_Key解密Encrypted_Handshake_Message,得到客户端加密前的Client_Finished。
Client_Finished应该为16字符的字符串,以14打头作为HandshakeType,以00000c作为长度标识。

b)         在服务端将Client_Finished消息之前的所有握手交互数据作PRF操作,得到服务端本地计算值;

c)         将本地计算值与解密得到的Client_Finished作比较,若相等则继续后续操作,若不相等则下发Alert报文。

2.         将所有握手交互数据作PRF操作,产生一个12字符的摘要赋值给Finished报文的verify_data属性:

verify_data = PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages))
其中handshake_messages包括从Client_Hello开始到Client_Finished的所有握手消息。Finished_label = “server finished”;

3.         服务端组装Server_Finished消息;

4.         利用Server_Write_Key将Finished消息用RC4_128算法加密,生成Encrypted_Handshake_Message后发送。



遇到的问题:

1.         服务端在收到客户端Client_Finished消息后,在对Client_Finished的正确性验证时,能够解密得到客户端加密前的Client_Finished。
同时解析得到的Client_Finished的报文格式满足协议规定的格式要求,即HandshakeType=14,Length=12 (0x00000c,亦即verify_data属性的长度)
但服务端计算得到的本地verify_data值与解析得到的报文中的verify_data值不一致。
就是这个步骤:
verify_data = PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages))
我这两天重复不断地将各种可能的结果组合测试,也将报文截下来,记录下报文中的数据,写测试类进行验证。

l          我能确保master_secret为正确的值,因为如果master_secret错误的话,无法生成正确的Client_Write_Key,就无法解析得到正确的Client_Finished;

l          我能确保Finished_label = “client finished”取值无误;

l          我能确保取到的handshake_messages是正确的值,已经和报文反复校验过,确认无误;

可是,本地计算的结果就是和解析报文得到的结果不一致!

2.         服务端在生成Server_Finished后需要利用Server_Write_Secret进行RC4_128加密,现有的RC4算法只能得到比输出字符串长度短的输出密钥。
但Server_Finished长度为16,需要得到32位的加密密钥,现有的RC4算法便无法实现。
RC4_128的加解密代码需要寻找支援。



请各位帮我查找相关的资源,或对我的问题提出建议。

谢谢!
页: [1]
查看完整版本: [求助]建立TLS通道最后一步Finished消息加解密