首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 互联网 >

MPPE协议引见

2012-07-27 
MPPE协议介绍本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,严禁

MPPE协议介绍
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝,转载,转载时请保持文档的完整性,
严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
参考文献: RFC3078

1. 前言MPPE(Microsoft Point-To-Point Encryption, 微软点对点加密)协议在RFC3078, 3079中定义, 描述了在PPP协议中进行数据加密的方法,通常用其实现PPTP模式的VPN。MPPE中的加密算法是固定的,使用RC4加密算法而不能是其他算法。2. CCP选项是否支持MPPE是PPP通信双方在CCP(Compression Control Protocol)协商过程中确定的, CCP协商数据格式如下:       0                   1                   2                   3       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      |      Type     |    Length     |        Supported Bits         |      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      |        Supported Bits         |      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   Type      18   Length      6   Supported Bits      这是个32位数, 格式如下, 大头方式:         3                   2                   1       1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      |             |H|                               |M|S|L|D|     |C|      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+各位说明如下:C : 在MPPC中定义D : 该位定义的功能已经作废L : 使用40位加密S : 使用128位加密M : 使用56位加密H : 表示使用无状态(stateless)模式, 每个包都是单独加密的其他位必须为0, 在协商时, 发起方设置所有能支持的加密位数(M, S, L), 响应方则在其中选择一种, 如果响应方支持的加密位数超过一种, 应该选择最强加密的那种(S > M > L)。3. MPPE包3.1 概述MPPE包传输前,PPP必须已经进入网络层协议阶段,CPP控制协议必须是“Opened”状态。每个PPP信息中只能携带一个MPPE包,对于加密了的PPP包,其PPP类型是0x00FD。每个MPPE数据包的最大长度等于PPP所能封装的最大信息长度。只对从0x0021到0x00FA类型的PPP包进行加密,加密后PPP包类型变为0x00FD,其他类型的PPP包不通过MPPE处理。3.2 数据包格式       0                   1                   2                   3       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      |          PPP Protocol         |A|B|C|D|    Coherency Count    |      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+      |      Encrypted Data...      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+参数说明如下:      PPP Protocol : 对MPPE来说是0x00FD,如果同时支持PPP压缩,该值是可以被压缩的;      Bit A :该位表示是否对加密表进行初始化,对于无状态模式,该位在每个包中都是置1的      Bit B :在MPPE中不考虑      Bit C :在MPPE中不考虑      Bit D :1表示该包是加密的,0表示是不加密的      Coherency Count : 12位数,表示PPP包的序号,单向增长,到0xfff后归0从新计数;      Encrypted Data :加密了的数据在同时使用MPPE和MPPC(微软PPP压缩协议)的情况,对发出的数据,先进行压缩再加密,对于接收的数据,先解密再解压。注意包的最前4字节是明文,不加密的,否则密钥更新就是先有鸡还是先有蛋的问题了。4. 加密处理 4.1 初始化会话密钥一般情况下会话密钥初始化是使用双方的证书来进行协商的,当然也可以通过其他方法来生成,通过预先共享的密钥PSK来生成。4.2 用会话密钥初始化RC4算法生成会话密钥后,使用rc4_set_key来设置RC4密钥:      rc4_set_key(RC4Key, Length_Of_Key, Initial_Session_Key)该函数可从openssl中查到。4.3 加密数据加密解密数据可用rc4函数处理:      EncryptedData = rc4(RC4Key, Length_Of_Data, Data)该函数可从openssl中查到。 5. 密钥处理密钥处理永远是加密通信的核心部分,只有保证双方的密钥是同步的,接收方才能正确解密发送方的数据,否则收到的只是一些垃圾数据。5.1 密钥更改如果使用了无状态模式,则对于每个包都需要重新交换一次会话密钥, 发送方必须在加密和发送数据前改变会话密钥, 接收方必须在接收数据后, 解密数据前改变会话密钥.对于状态保存模式, 发送方必须在包序号的后8位是0xff时更新会话密钥,同样是在加密和发送数据前; 接收方接收到序号后8位是0xff的包后, 在解密前改变会话密钥.MPPE密钥更改算法:      /*       * SessionKeyLength is 8 for 40-bit keys, 16 for 128-bit keys.       *       * SessionKey is the same as StartKey in the first call for       * a given session.       */需要3个参数作为输入: 初始密钥, 老会话密钥, 会话密钥长度一个参数作为输出: 中间密钥是使用SHA1算法对初始密钥, 当前会话密钥进行HASH后得到新的会话密钥第一次使用时, 老会话密钥也用初始密钥      void      GetNewKeyFromSHA(      IN  unsigned char *StartKey,      IN  unsigned char *SessionKey,      IN  unsigned long SessionKeyLength      OUT unsigned char *InterimKey )      {// SHA1输出是160位, 即20字节         unsigned char  Digest[20];         ZeroMemory(Digest, 20);         /*          * SHAInit(), SHAUpdate() and SHAFinal()          * are an implementation of the Secure          * Hash Algorithm [7]          */         SHAInit(Context);// SHA1(初始密钥)         SHAUpdate(Context, StartKey, SessionKeyLength);// SHA1(40字节的填充数据1)         SHAUpdate(Context, SHApad1, 40);// SHA1(原会话密钥)         SHAUpdate(Context, SessionKey, SessionKeyLength);// SHA1(40字节的填充数据2)         SHAUpdate(Context, SHApad2, 40);         SHAFinal(Context, Digest);// 复制最后的SH1结果到中间密钥空间         MoveMemory(InterimKey, Digest, SessionKeyLength);      }得到中间密钥后, 再用中间密钥使用rc4算法加密中间密钥得到新的会话密钥:// 用中间密钥设置RC4密钥      rc4_set_key(RC4Key, Length_Of_Key, InterimKey)// 用RC4加密中间密钥      SessionKey = rc4(RC4Key, Length_Of_Key, InterimKey)可见, 如果初始密钥固定, 以后每次更新计算出的会话密钥都是相同的.如果不是128位加密, 会将新会话密钥的某些字节取固定值以减少强度:对于40位加密, 生成的新会话密钥前3字节固定为: 0xD1, 0x26, 0x9E对于56位加密, 生成的新会话密钥前1字节固定为: 0xD15.2 密钥同步5.2.1 无状态模式无状态模式下每个包加密的密钥都是不同的, 每个包都要重新计算会话密钥, 每个包都会设置“A”标志。当接收方收到的包的序号(C1)大于上次接收包的序号(C2)时, 接收方在解密前必须执行N=C1-C2次密钥更改计算, 一般情况下没丢包时N为1, 异常情况下N会大于1。5.2.2 状态保持模式在状态保持模式下,发送方发现序号的后8位已经为0xff时更新密钥,更新完再加密和发送,包中设置“A”标志;接收方接收到“A”标志包时先更新密钥,再解密。如果发生丢弃“A”标志包的情况,接收方会发现接收的数据包序号后8位比前面的包小,这时接收方要进行密钥更新操作并发送一个CCP的复位请求包。如果丢失的是超过256个以上包的情况,发送方可能已经更新了两次密钥了,接收方应该(SHOULD)能检测这种情况并进行相关密钥更新操作,但不是必须的,RFC中没有规定如何检测,我想是根据是否能正确解密数据包来判断吧。在状态保持模式下接收方检测到丢包情况时,接收方必须丢弃该包,并发送CCP的复位请求包,在收到“A”标志的数据包前丢弃接收到的所有其他包。当收到“A”标志包时,将该包序号作为接收方新的包序列号,并用当前的会话密钥更新RC4,如前所述,这个会话密钥已经是更新后的了,和发送方保持相同。重新设置RC4密钥:      rc4_set_key(RC4Key, Length_Of_Key, SessionKey)发送方接收到CCP复位请求包时,也要用当前的会话密钥(该会话密钥和接收方相同)更新RC4,然后在下一个包中设置“A”标志,这样就可以继续保证密钥同步。由于PPP都用在不是很可靠的通信线路上,因此最常用的还是无状态模式。6. 实现在Linux下提供了MPPE的实现,其中加密部分是内核中的处理,PPP协商是用户空间的处理,以前是需要补丁才能实现,但2.6.14版本后已经将MPPE纳入内核中不需要补丁了,不过在2.6的MPPE实现中,加密算法不是RC4而是ARC4,ARC4只是个非常简单的流异或处理,几乎说不上有什么强度,比RC4差很多,不知道什么样的客户端能和其通;而原来2.4内核的MPPE补丁是支持RC4的,可以使用128位的高强度加密,对于win2K,必须打了SP2后才能支持128位的PPTP,否则只支持56位。 7. 结论MPPE提供了PPP通信的机密性,使用的固定的加密算法,没使用认证,因此比IPSEC简单了很多,通常最好是使用无状态模式使每个包都由不同的密钥进行加密。MPPE有Linux的实现补丁,新2.6内核也支持了MPPE,不过其加密算法有疑问。

热点排行