我们正在研究AS2的实现,并希望能够构建有意义的测试用例以与SoapUI或Postman一起使用。
为此,我们有两种方法:
只是尝试从现有客户端进行tcp-dump / trace调用
从普通EDI文档开始手动构建一些简单的调用
或由于各种原因而丢弃(1)的原因,因此必须与(2)一起使用,并且需要一些文档。
Oracle的这份文档是一个很好的起点:https://docs.oracle.com/cd/E19398-01/820-1228/agfat/index.html
但是我们真的找不到从ORDERS edi文档(我们已经拥有)开始构建AS2请求的分步指南。
理想情况下,我需要一份分步指南,内容如下:
生成私人证书:+命令行
加密EDI文档:+命令行+ sampleoutput
创建签名:+命令行+ sampleoutput
构建S / MIME包:+命令行+ sampleoutput
通过HTTP / S发送:+命令行+ samplehttptrace
最佳答案
传送讯息
要发送消息,我们需要一个带有消息的文件,两边都有两对密钥(每个伙伴都有一对用于签名的密钥和另一对用于加密的密钥,每对密钥都由公共和私有密钥组成)。在本教程中,我们将对每个伙伴使用相同的密钥对进行签名和加密。
产生金钥
使用OpenSSL创建两对密钥:
openssl req -x509 -newkey rsa:2048 -keyout P1_private.pem -out P1_public.pem -days 365
第二对相同:
openssl req -x509 -newkey rsa:2048 -keyout P2_private.pem -out P2_public.pem -days 365
扩展私钥文件
P1_private.pem和P2_private.pem仅包含私钥。 OpenSSL支持扩展的PEM格式,其中私钥和公钥都可以在一个文件中。这简化了一些OpenSSL命令(可以给一个文件而不是两个文件)。本教程假定已完成:
cat P1_public.pem >> P1_private.pem
cat P2_public.pem >> P2_private.pem
否则,请查看《 OpenSSL命令手册》以了解如何在需要的地方指定第二个文件。
签名文件
假设我们要通过AS2协议从P1 partner =>到P2发送GETMSG.edi文件,并进行签名和加密。首先,我们向其中添加适当的MIME标头:
Content-Type: application/edi-consent
Content-Disposition: attachment; filename="GETMSG.edi"
UNA:+./*'
UIB+UNOA:0++2289+++77777777:C:PASSWORDA+111111:M+19971001:074620'
UIH+SCRIPT:010:006:GETMSG+111'
UIT+111+2'
UIZ++1'
将新文件另存为GETMSG.msg
然后使用发送伙伴P1的私钥对文件签名:
openssl smime -sign -in GETMSG.msg -out GETMSG_SIGNED.msg -signer P1_private.pem
注意:OpenSSL会放置以'x-pkcs7-'开头的旧MIME类型,某些应用程序(pyAS2)只能处理新的MIME类型,而无需使用eks'pkcs7-'。只需从结果文件中的所有位置删除“ x-”即可。
加密
现在我们有了多部分的附件,第一部分是文件内容,第二部分是签名。现在,我们使用接收伙伴P2的公钥对其进行加密:
openssl smime -encrypt -in GETMSG_SIGNED.msg -out GETMSG_ENC.msg -des3 P2_public.pem
现在可以将带有附加AS2标头的结果文件GETMSG_ENC.msg发送给收件人。
注意:OpenSSL会放置以'x-pkcs7-'开头的旧MIME类型,某些应用程序(pyAS2)只能处理新的MIME类型,而无需使用eks'pkcs7-'。只需从结果文件中的所有位置删除“ x-”即可。
通过cURL发送
要使用cURL发送,我们必须将POST请求的标头和正文分开。从文件GETMSG_ENC.msg中删除所有标头(应以“ MI ..”开头)。
假定P2 URL为“ http://localhost:8080/pyas2/as2receive”,请使用此命令将其从P1(AS2 ID:p1as2)发送到P2(AS2 ID:p2as2):
set NOW=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
curl -i -X POST-H "Content-Disposition: attachment; filename=\"smime.p7m\""-H "Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\""-H "Content-Transfer-Encoding: base64"-H "AS2-TO: p1as2"-H "AS2-FROM: p2as2"-H "AS2-VERSION: 1.2"-H "MESSAGE-ID: <openssl%NOW%@LOCALHOST>"-H "Disposition-Notification-To: response@localhost"-H "DISPOSITION-NOTIFICATION-OPTIONS: signed-receipt-protocol=required, pkcs7-signature; signed-receipt-micalg=optional, sha1"--data-binary @GETMSG_ENC.msg http://localhost:8080/pyas2/as2receive
注意:此命令还将请求带有签名的MDN(因为存在Disposition-Notification-To和DISPOSITION-NOTIFICATION-OPTIONS的值)。
接收讯息
在接收端已经发生以下情况。这将包括解密消息,验证签名,提取有效载荷以及准备确认或消息处理通知(MDN)。它还需要计算要在确认中发送的接收消息(MIC)的哈希。
解密请求
使用OpenSSL命令解码保存为smime.p7m的请求内容:
openssl smime -decrypt -in smime.p7m -recip P2_public.pem -inkey P2_private.pem -out request.txt
验证签名
openssl smime -verify -in request.txt -nosigs -noverify -signer P2_public.pem -out original.txt
计算接收内容MIC
必须在带有MIME标头的原始文件上计算接收到的内容的摘要,在我们的示例中,该内容就是GETMSG.msg的内容。
openssl dgst -sha1 -binary GETMSG.msg | openssl enc -e -base64
注意:在现实生活中,接收者必须从multipart / signed类型的解密内容中提取该内容。第一部分是接收到的内容。
邮件处理通知
未签名的消息处理通知或确认看起来像是多部分报告:
Content-Type: multipart/report; report-type="disposition-notification"; boundary="===============1785295974=="
--===============1785295974==
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
The AS2 message has been processed. Thank you for exchanging AS2 messages with Pyas2.
--===============1785295974==
Content-Type: message/disposition-notification; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Reporting-UA: Bots Opensource EDI Translator
Original-Recipient: rfc822; p1as2
Final-Recipient: rfc822; p1as2
Original-Message-ID: <openssl20170706165018@LOCALHOST>
Disposition: automatic-action/MDN-sent-automatically; processed
Received-content-MIC: 1GZ1SDk5vvGz5YFGYP6lfhk4MXE=, sha1
--===============1785295974==--
签名邮件处理通知
如果请求签名的MDN(取决于“ Disposition-Notification-Options” HTTP标头),则上面显示的多部分报告将打包为multipart / signed。秒部分是上面显示的第一部分的签名。如果我们假设mdn.txt包含如上所述的未签名的MDN,则对其进行签名:
openssl cms -sign -signer P2_private.pem -in mdn.txt -out mdn_signed.txt
现在,我们只需要在通过HTTP传输它之前(取自pyAS2的实际响应),就可以根据请求的MDN类型,在mdn.txt或mdn_signed.txt的顶部添加一些特定于AS2的标头:
ediint-features: CEM
as2-from: p1as2
user-agent: PYAS2, A pythonic AS2 server
AS2-Version: 1.2
as2-to: p2as2
date: Thu, 06 Jul 2017 16:50:18 +0200
X-Frame-Options: SAMEORIGIN
Message-ID: <149935261885.25752.7388914440262498594@HOSTNAME>
Transfer-Encoding: chunked
Server: pyas2-webserver
基于源:pyAS2文档,OpenSSL文档,NCPDP SCRIPT消息示例。