前一篇文章《biztalk中消息加密解密的例子》演示的是biztalk系统àbiztalk系统的加密解密,这要求通讯双方都是biztalk的系统。如果加密解密的一方是biztalk系统,另一方是自己开发的定制应用系统,定制系统该怎么加密消息发送到biztalk系统,又怎么解密从biztalk发送来的加密消息?
这就需要知道biztalk对加密的消息的结构,加密消息中那一部分是对称密钥、哪一部分是实际被加密的消息,是否还包含其他内容,他们之间是如何组合在一起的。
这部分就是分析biztalk的加密消息的结构,尝试解析biztalk加密的消息结构。
发送管道中的MIME/SMIME encoder组件的属性设置为:
l Content transfer encoding – Base64
l Encrypt alogrithm – DES3
l Send boby part as attachment -- false
l Signaltrue type – NoSign
设计三个消息,两个消息是同一个schema,其中一个长度短点的消息a,一个长度稍长点的消息b;还有一个是不同的schema的消息消息c。
1、 消息a的内容
1.1. 消息a原始内容
<ns0:id xmlns:ns0="http://CertEndryptMsg.MsgScheSim">simple</ns0:id>
1.2. 消息a加密后的内容
Content-ID: {C101BFE8-B609-4B 8A -834A -B7874097E0BD}
Content-Description: body
Bcc:
MIME-Version: 1.0
Content-type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p 7m "
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAWMRQwEgYDVQQDEwtSb290IEFnZW5jeQIQ
WRRSbjmnU5FINb3pvccz7jANBgkqhkiG9w0BAQEFAASBgHr2zmAgr8kqK0FuEkAkg5lfahVrNuog
QvV+HbU0IKcI1AtsyH20aDwVLxankITC4Umzq47ZcnmNV+HiuNvHKaaVC/0wqwtLylKoKWXKTGoi
/dAewRHE3cV3xJRYFYEnxxDuTH5ORcXdzNmEx+ue+LQrN/m97b31Xe+V3n/ukL3TMIAGCSqGSIb3
DQEHATAUBggqhkiG9w0DBwQIGpLuzeYobt+ggASBsPvdVe4wYYawE5PZTz9UsQwta8PiNHo1NXLU
3XBa7hDcmc2FlO3PtiZ9tWlOZjjopsp3kqIj9w7HLWm/JrFR2sS0qEupZm7jvqSlREcnC8ql83xh
VcuOHYbwhhimGyfM4i5tHZbbVGzHHaxwfas3+hAQbzYyfScmP2XCZUj99+KntZS81NstQ7GCyTxa
v9pJF+8SZKMVmQ3EIdlcK75pPukoEzZlgNuhizgqZr7LZZYOAAAAAAAAAAAAAA==
很明显,这是base64编码,解码后这部分base64编码内容的二进制内容是这样的:
2、 消息b的内容
2.1. 消息b原始内容
<ns0:id xmlns:ns0="http://CertEndryptMsg.MsgScheSim">This is a more long message than previous one.</ns0:id>
2.2. 消息b加密后的内容
Content-ID: {2EBD 41A 2 -3A 6E-421D-AF 6F -A89DD9728732}
Content-Description: body
Bcc:
MIME-Version: 1.0
Content-type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p 7m "
Content-Transfer-Encoding: base64
MIAGCSqGSIb3DQEHA6CAMIACAQAxgcQwgcECAQAwKjAWMRQwEgYDVQQDEwtSb290IEFnZW5jeQIQ
WRRSbjmnU5FINb3pvccz7jANBgkqhkiG9w0BAQEFAASBgMjJbqSM2Els 6l 9EJC7TwK++U 08A 8exd
TLH2/CW7csr0il6ZqrIPH06HJj6qdcT4ffbw7h1AwSJFl+ukRTq6ejX+z071jdCAt728sdnRpsx6
uiK8GPo7dYFGpZCNnnnawJtH8R6ViG 36M 1Xiu2snu83beGywYcCpandvChXbparLMIAGCSqGSIb3
DQEHATAUBggqhkiG9w0DBwQI/U1IxtQCAAqggASB6E+uliVdCFdqjPqycM1MPX+RlXtatkbdPkYC
o9hzcglQoVaU744kw3iiaSA6gwSVTyNMf1UhKUNvGAP6Hi6ngJkg8P9JIvrtaODhNvLS9N4LWCWa
JbPMkUHEef6ChFFsLC49cH6d2dillVRzsi0AISLWp9Vzm1BX+w4jWoZPahxAXTSxhVoWq7Z8PJsq
8R/2xOBYWNwlp+aPVurE+n5jTJus7SKkIqDnbP+U8TrwbEB8EFUygN 0a 3hMDSJXeSnWvGUG 3m 1aH
rrpN9zGQs2cRMfIKjSm2yGyjbQ+hF4kAOyQRDKtnEp/E6BEAAAAAAAAAAAAA
解码后base64编码内容的二进制内容:
消息c的形式跟上面两个消息类似,具体内容就不贴出来了。
3、 分析加密消息的格式
用证书加密的消息,一般的组成应该是:使用RSA的公钥加密的对称密钥 + 使用对称密钥加密的实际信息内容。
分析biztalk的加密消息,主要需要完成的任务是:
l 在biztalk生成的加密消息中分解出对称密钥
l 使用证书中的私钥解密对称密钥
l 在biztalk生成的加密消息中分解出使用对称密钥加密的实际消息密文
l 使用对称密钥解密实际消息密文
消息的分析图
3.1. 确定对称密钥的位置
根据Dotnet framework的RSA加密实现,使用1024为的密钥加密,原料应该是128字节(1024位)的byte[]的原始数据,加密后的数据也是128字节(1024位),如果明文不足128字节,RSACryptoServiceProvider会自动用随机数补足128字节。
Dotnet的RSA实现还有个特点,它必须要在明文中添加一些随机数,所以明文不能把128字节占满,实际测试,明文最多为117字节,留下的空间用来填充随机数。
所以RSA加密后的密文一定是128字节的,根据这点,对三个消息的加密后的二进制密文进行搜索,从0-127开始,看这128个字节的内同是否能够被证书的私钥正确的解密,如果不行,则整个向后移动一个字节,检测1-128这个范围的128字节的内同是否可以被正确解密,以此类推,直到找到可以被证书的私钥正确解密的那128个字节。
通过编制程序,在整个两进制密文进行逐个搜索.
搜索结果:三个密文都是在91-218这范围的128个字节被证书的私钥正确的解密出来,解密后是个24字节的数据。
这三个测试消息,两个架构相同,但内容不同,另一个消息架构都不同,能得到这样的结果,说明在发送管道的MIME/SMIME encoder组件为前面设置的那样的前提下,加密消息的对称密钥在密文中的位置就是91-218这个范围。
在上图的红色的B区域就是加密后的对称密钥在密文中的位置。
3.2. 区域A
密文的0-90这个位置的91个字节,在三个密文中内容一摸一样,估计其中内容应该是MIME/SMIME encoder组件配置的一些属性,比如加密消息的对称加密算法选的是哪种,消息是否使用了前面,是的话是哪种签名等等。
里面的具体格式不详,只是猜测。
在上图的蓝色的就是表示这部分的A区域的位置。
3.3. 区域C
密文的219-245这27个字节,在三个消息的密文中也都是一摸一样,应该是跟消息内同本身没有关系,所以这部分的内容也可以从实际消息中排除,不过这部分表示什么不详。
在上图的绿色的就是表示这部分的C区域的位置。
3.4. 加密消息内容部分
密文中除了上述三个部分,剩下的部分按理就应该是用对称密钥加密的实际消息了。下文中把除了上述部分以外的可能是加密后的实际消息部分成为“D部分”。
下面就开始一步步的对这剩下部分的内容进行解密测试。
前面步骤已经在密文中找到对称密钥,解密后得到24字节的对称密钥数据。
MIME/SMIME encoder组件中配置的加密算法是DES3,即TripleDES算法。根据dotnet framework的TripleDES算法的实现,TripleDES算法的key可以为16字节或者24字节,IV初始矢量为8字节。密文中的对称密钥数据为24字节,那么可以肯定其中16字节为key,另外8字节为IV。
分下面两种情况进行测试:
l 前16字节为key,后8字节为IV
l 前8字节为IV,后16字节为key
对“D部分”逐个字节分段进行扫描解密测试。假设“D部分”的长度为n,测试步骤如下:
l 开始以“D部分”的0字节处为开始,最后一个字节n-1处为结束,对这段内容用前面获得的密钥解密测试,然后还是以“D部分”的0字节处为开始,以最后第二个字节n-2处为结束,对这段内容用前面获得的密钥解密测试,以此类推,直到结束处跟0字节处相遇。
l 开始以“D部分”的1字节处为开始,重复上面的循环过程。
l 直到以“D部分”的n-1字节处为开始,重复第一步的循环过程。
这样的测试应该是把“D部分”的内容所有组合都包括了,看测试结果:
所有的循环测试中,三个加密消息,基本上都遇到有20多个可以被解密的内容,但是被解出来的内容跟消息的原始内容都不同,都是乱码,看似碰巧密文内容可以被解密,而不是实际的密文被正确解密。
至此,分析biztalk的加密消息尝试告失败。在网上查找也没有找到微软biztalk加密消息的格式规范,目前来看,估计需要微软公开biztalk的消息加密细节后才有可能让开发者自编代码来解析biztalk生成的加密消息或者生成biztalk认识的加密消息。
二、 Biztalk消息加密的现实方案
1、 加密解密双方都使用biztalk
在一个组织内部有个biztalk服务器,组织内部的整合属于EAI的范畴,所有需要集成的应用都在组织内部的局域网内,或者通过VLAN、VPN组织到一个内网内。在内网的应用跟biztalk之间进行通讯不需要进行加密,因为内网跟外网有防火墙隔离。
组织之间的交换数据属于B2B的范畴,组织之间通讯一般要经过外网,对消息的安全性需要更多考虑,所以组织之间的消息交换可以通过各自的biztalk对消息进行加密和解密。
2、 加密解密双方都是用自编代码或第三方方案
如果跟biztalk交换消息的一方不是biztalk,那么就不能使用biztalk的加密机制,这时可能需要自编代码进行加密解密,自己定义加密数据的格式规范,非biztalk端和biztalk端的加密解密代码都需要自己编写。
非biztalk端的代码根据自定义的加密格式规范任意编写,biztalk端的加密解密功能一般需要做成管道组件,在管道组件中写自己的加密解密代码。
或者采用第三方的方案,比如AS2,是个安全交换商业文件的标准,本身可以对交换消息进行加密处理。