josephzy
发贴: 2
积分: 0
|
于 2006-12-17 14:28
在做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[12];
} 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的加解密代码需要寻找支援。
请帮我查找相关的资源,或对我的问题提出建议。
谢谢!
|