Character encoding 如何使用;引述“可打印”;使用BizTalk AS2接收的内容传输编码?

Character encoding 如何使用;引述“可打印”;使用BizTalk AS2接收的内容传输编码?,character-encoding,biztalk,content-type,mime,Character Encoding,Biztalk,Content Type,Mime,我目前正在使用BizTalk Server 2013 R2与许多不同的贸易伙伴使用AS2交换EDI以及非EDI文档。我最近添加了一个新的贸易伙伴,在成功收到大量文档后,我开始时不时地看到此错误: 接收管道“Microsoft.BizTalk.EdiInt.DefaultPipelines.AS2Receive,Microsoft.BizTalk.Edi.EdiIntPipelines,Version=3.0.1.0,Culture=neutral,PublicKeyToken=31bf3856a

我目前正在使用BizTalk Server 2013 R2与许多不同的贸易伙伴使用AS2交换EDI以及非EDI文档。我最近添加了一个新的贸易伙伴,在成功收到大量文档后,我开始时不时地看到此错误:

接收管道“Microsoft.BizTalk.EdiInt.DefaultPipelines.AS2Receive,Microsoft.BizTalk.Edi.EdiIntPipelines,Version=3.0.1.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”中组件“Microsoft.BizTalk.EdiInt.PipelineComponents”的输出消息由于以下错误而挂起:不支持引用可打印的内容传输编码。。 挂起消息的序列号为2

经过一些调查,我发现当所附的XML有效负载包含非ASCII字符时,相关贸易伙伴的AS2平台有时会将MIME主体部分的
内容传输编码设置为可引用打印。发生这种情况时,消息将被挂起(不可恢复),并出现上述错误

从该贸易伙伴接收的消息是加密和签名的,但不是压缩的-并使用配置了开箱即用的AS2Receive管道的HTTP请求-响应(双向)端口接收。我曾尝试使用自定义管道和AS解码器、S/MIME解码器和AS2反汇编程序组件,但这似乎没有任何效果-错误保持不变

我也尝试过从贸易伙伴处接收未加密的消息(通过双方协议),但似乎在这里做错了什么,并且传递到消息框的消息最终没有被正确分解(MIME部分边界和AS2签名在实际消息负载中仍然可见)。因为贸易伙伴无论如何都不允许在生产环境中发送未加密的消息,所以我需要让它与加密一起工作。他们也不能改变其平台的行为,因为据报道,这将影响其所有其他贸易伙伴

以下是在挂起点接收的加密和签名AS2消息的未展开HTTP头(省略号表示编辑值):

日期:2020年1月20日星期一格林尼治标准时间17:30:53
内容长度:8014
内容类型:应用程序/pkcs7 mime;name=“smime.p7m”;smime类型=封装数据
发件人:。。。
主持人:。。。
用户代理:Jakarta Commons HttpClient/3.1
AS2至:。。。
主题:AS2消息来自。。。到
消息Id:
处置通知:。。。
处置通知选项:签名接收协议=可选,pkcs7签名;签名收据micalg=可选,sha1
AS2发件人:。。。
AS2版本:1.1
内容处置:附件;filename=“smime.p7m”
X-Original-URL:/as2

以下是源方未加密发送完全相同消息时的未加密(省略号表示编辑内容)有效负载:

------=_Part_16155_1587439544.1579506174880
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

...
------=_Part_16155_1587439544.1579506174880
Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

...
------=_Part_16155_1587439544.1579506174880--


问题:BizTalk Server是否支持引用的可打印编码方法?如果有,我做错了什么?如果没有,我的解决方案是什么?

我已经向Microsoft BizTalk技术支持部门申请了该问题。他们的回答是

引用的可打印编码不受MS BizTalk Server 2013R2支持,并且很可能不受MS BizTalk Server 2020支持


对于其他可能遇到同样问题的人,我想我会分享我最终得到的解决方案

由于在AS2接收管道处理过程中遇到错误,因此我的解决方案自然集中于创建一个自定义接收管道组件,该组件的功能与现成的AS2解码器组件大致相同,但支持引用的可打印编码方法:


1.解码和解密CMS/PKCS#7数据信封

这实际上是最简单的步骤,只有5行代码:

EnvelopedCms EnvelopedCms=新的EnvelopedCms();
信封CMS.解码(加密数据);
Decrypt();
字节[]decryptedData=envelopedCms.Encode();
string decryptedMessageString=Encoding.ASCII.GetString(decryptedData);
-encryptedData是从HTTP适配器接收的AS2消息的正文部分数据流实例化的字节数组

-Decrypt方法会自动搜索用户和计算机证书存储区以查找适当的证书私钥,并使用该私钥对AS2有效负载进行解密。有关“EnvelopedCms”类的更多信息,请遵循以下步骤


2.将有效负载中任何引用的可打印内容转换为普通UTF-8文本

首先,我们必须从解密负载开头的内容类型字符串中获取MIME边界名称:

int firstBlankLineInMessage=decryptedMessageString.IndexOf(Environment.NewLine+Environment.NewLine);
string contentType=decryptedMessageString.Substring(0,firstBlankLineInMessage);
Regex boundaryRegex=new Regex(“boundary=\”(?.*)\”;
Match boundaryMatch=boundaryRegex.Match(contentType);
如果(!boundaryMatch.Success)
抛出新异常(“未能从内容类型获取边界名称”);
字符串boundary=“--”+boundaryMatch.Groups[“boundary”].Value;
然后,我们拆分信封并重新合并,不包含内容类型标题部分:

string[]messageParts=DecryptedMessageSting.Split(新字符串[]{boundary},StringSplitOptions.RemoveEmptyEntries);
字符串signedMessageString=boundary+messageParts[1]+boundary+messageParts[2]+boundary+“--\r\n”;
接下来,我们在MIME正文部分标题中获得“内容传输编码”值:

int firstBlankLineInBodyPart=messageParts[1].IndexOf(Environment.NewLine+Environment.NewLine);
字符串partHeaders=messageParts[1]。子字符串(0,firstBlankLineInBodyPart);
正则表达式