AS2协议(Applicability Statement 2)是在互联网上安全可靠地传输数据的标准规范。它经过使用数字证书、加密机制保障传输数据的安全性。算法
OpenAS2 是用 Java 实现 AS2 的开源项目, 基于FreeBSD开源协议,OpenAS2 使您可以在交易伙伴之间传送和接收 EDI-X十二、EDIFACT、XML 或二进制形式的 AS2 消息。sql
Open AS2 下载地址:sourceforge.net/projects/op…shell
下载解压,无需安装便可运行,目录结构以下:数据库
.
├── OpenAS2HowTo.pdf
├── RELEASE-NOTES.md
├── bin
├── changes.txt
├── config
├── lib
└── resources
复制代码
在执行脚本以前,须要确认的是系统中已经设置了JAVA_HOME
环境变量。安全
给启动脚本添加执行权限bash
chmod +x ./bin/start-openas2.sh
复制代码
启动OPEN AS2服务器
./bin/start-openas2.sh
复制代码
若是一切正常的话会看到如下提示app
FINE OpenAS2Server: OpenAS2 Server v2.9.0 started.async
$ ./gen_p12_key_par.sh clinflash-pv clinflash-pv SHA256 \
"CN=www.clinflash.net, OU=Clinflash, O=Clinflash, L=Shanghai, S=Shanghai, C=CN"
Generate a certificate to a PKCS12 key store.
Generating certificate: using alias clinflash-pv to clinflash-pv.p12
Do you wish to execute this request? [Y/N]Y
Enter password for keystore:123456
存储在文件 <clinflash-pv.cer> 中的证书
Generated files:
PKCS12 keystore: clinflash-pv.p12
Public Key File: clinflash-pv.cer
复制代码
配置文件位于config目录,其中各个文件有不一样做用tcp
另外,config.xml文件中的配置若是发生更改须要重启应用才会生效,而其它文件配置发生更改会自动刷新。
properties节点中定义了一些属性值,这些属性值能够在其余地方以变量方式使用。
<properties storageBaseDir="%home%/../data" log_date_format="yyyy-MM-dd HH:mm:ss.SSS" sql_timestamp_format="yyyy-MM-dd HH:mm:ss.SSS" as2_message_id_format="OPENAS2-$date.ddMMyyyyHHmmssZ$-$rand.UUID$@$msg.sender.as2_id$_$msg.receiver.as2_id$" as2_async_mdn_url="http://localhost:10081"/>
复制代码
例如使用storageBaseDir
这个属性值:
<processor classname="org.openas2.processor.DefaultProcessor" pendingMDN="$properties.storageBaseDir$/pendingMDN3" pendingMDNinfo="$properties.storageBaseDir$/pendinginfoMDN3">
</>
复制代码
<certificates classname="org.openas2.cert.PKCS12CertificateFactory" filename="%home%/as2_certs.p12" password="testas2" interval="300"/>
复制代码
%home%
表示当前目录,也就是config目录,filename
和password
的属性值须要改为咱们的keystore文件和密码。
这里仅仅定义了伙伴关系文件的位置,详细的配置信息在这个文件中。
<partnerships classname="org.openas2.partner.XMLPartnershipFactory"
filename="%home%/partnerships.xml"
interval="120"/>
复制代码
OPEN AS2会轮询扫描指定的目录,寻找发送给伙伴的文件。目录扫描器会在两个连续周期检查发现的文件大小是否发生变化,若是没有变化则会将此文件加入发送队列中。
用于存放发送文件的目录能够是一个伙伴的专有目录,也能够是一个通用目录。若是使用通用目录,则经过解析文件名肯定伙伴的身份。
如下是发送文件相关的关键属性:
outboxdir
- 发送文件的扫描目录
errordir
- 发送文件出错后存放文件的目录
interval
- 扫描目录的周期(秒)
sendfilename
- 发送给远程伙伴的消息是否必须包含文件名
mimetype
- 指定发送消息中文件的扩展类型
<!-- This directory polling module will parse the filename to get a sender, receiver and name of file to send to partner. For instance, a file named MyComapny_OID-PartnerB_OID-OrderID-745634.edi would be sent from MyCompany to PartnerB. The name of the file sent to the partner will be "OrderID-745634.edi" -->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule" outboxdir="$properties.storageBaseDir$/toAny" errordir="$properties.storageBaseDir$/toAny/error" interval="5" delimiters="-" mergeextratokens="true" sendfilename="true" format="sender.as2_id, receiver.as2_id, attributes.filename" mimetype="application/EDI-X12" />
复制代码
<!-- This directory polling module will is dedicated to sending to partner PartnerA_OID -->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule" outboxdir="$properties.storageBaseDir$/toPartnerA/" errordir="$properties.storageBaseDir$/toPartnerA/error" interval="5" defaults="sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerA_OID" sendfilename="true" mimetype="application/EDI-X12"/>
<!-- This directory polling module will is dedicated to sending to partner PartnerB_OID -->
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule" outboxdir="$properties.storageBaseDir$/toPartnerB" errordir="$properties.storageBaseDir$/toPartnerB/error" interval="5" defaults="sender.as2_id=MyCompany_OID, receiver.as2_id=PartnerB_OID" sendfilename="true" mimetype="application/EDI-X12"/>
复制代码
其中,“defaults”属性指定了目录中全部文件的发送方和接收方的AS2 ID。
此外,还能够限制发送文件的扩展名,fileextensionfilter
指定了经过的文件扩展名,fileextensionexcludefilter
指定了忽略的文件扩展名。
fileextensionfilter="doc, docx, txt, edi"
fileextensionexcludefilter="tmp"
复制代码
从2.1.0版本开始,OPEN AS2会跟踪消息传输和接收过程,并将消息状态写入内嵌的H2数据库中。
如下是默认配置:
<module classname="org.openas2.processor.msgtracking.DbTrackingModule"
use_embedded_db="true"
force_load_jdbc_driver="false"
db_user="sa"
db_pwd="OpenAS2"
db_name="openas2"
table_name="msg_metadata"
db_directory="%home%/DB"
jdbc_driver="org.h2.Driver"
jdbc_connect_string="jdbc:h2:$component.db_directory$/$component.db_name$"
sql_escape_character="'"
tcp_server_start="true"
tcp_server_port="9092"
tcp_server_password="openas2"
/>
复制代码
除了使用内嵌的H2数据库,还能够使用任何有JDBC驱动的数据库(如Oracle, MySql or Postgresql等)。使用外部数据库时须要将JDBC驱动放入lib
目录,同时将use_embedded_db
属性值设为"false",还要修改其它部分属性值。
下面的配置以Postgresql为例:(用户名、密码根据实际状况填写)
<module classname="org.openas2.processor.msgtracking.DbTrackingModule" use_embedded_db="false" force_load_jdbc_driver="false" db_user="sa" db_pwd="OpenAS2" db_name="openas2" db_directory="%home%/DB" jdbc_driver="org.postgresql.Driver" jdbc_connect_string="jdbc:postgresql://localhost:5432/$component.db_name$" sql_escape_character="'" />
复制代码
若是消息传输出错,系统会自动无限重试,但能够配置重试次数。
config.xml
中的配置的重试次数会被partnerships.xml
中配置的重试次数覆盖。
<module classname="org.openas2.processor.sender.AS2SenderModule" retries="5"/>
<module classname="org.openas2.processor.sender.MDNSenderModule" retries="3"/>
复制代码
另外还有一些其它配置,如文件名解析、代理服务器、健康检查等,能够查看OPEN AS2的使用说明 OpenAS2HowTo.pdf。
partnerships.xml
中配置了信息交换伙伴的全部信息
<partner>
定义了信息交换的贸易伙伴信息<partnership>
定义了2个贸易伙伴之间的关系下面的示例是本身公司和2个交易伙伴配置:
<partnerships>
<partner name="MyCompany" as2_id="MyCompany_OID" x509_alias="mycompany" email="as2msgs@openas2.com"/>
<partner name="PartnerA" as2_id="PartnerA_OID" x509_alias="partnera" email="as2msgs@partnera.com"/>
<partner name="PartnerB" as2_id="PartnerB_OID" x509_alias="partnerb" email="as2msgs@partnerb.com"/>
<partnership name="MyCompany-to-PartnerA">
<sender name="MyCompany"/>
<receiver name="PartnerA"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="binary"/>
<attribute name="compression_type" value="ZLIB"/>
<attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
<attribute name="as2_url" value="http://localhost:10080"/>
<attribute name="as2_mdn_to" value="edi@myCompany.com"/>
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA256"/>
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="PartnerA-to-MyCompany">
<sender name="PartnerA"/>
<receiver name="MyCompany"/>
</partnership>
<partnership name="MyCompany-to-PartnerB">
<sender name="MyCompany"/>
<receiver name="PartnerB"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="8bit"/>
<attribute name="compression_type" value="ZLIB"/>
<attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
<attribute name="as2_url" value="https://as2.partnerb.com:8443"/>
<attribute name="as2_mdn_to" value="edi@myCompany.org"/>
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA1"/>
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="PartnerB-to-MyCompany">
<sender name="PartnerB"/>
<receiver name="MyCompany"/>
</partnership>
</partnerships>
复制代码
有一点须要说明的是:即便数据传输是单向的,也要配置双向的<partnership>
。
Message ID用于惟一标识发送给伙伴的消息,默认格式为
OPENAS2-$date.ddMMyyyyHHmmssZ$-$rand.UUID$@$msg.sender.as2_id$_$msg.receiver.as2_id$
复制代码
在config.xml中能够经过as2_message_id_format
属性全局设置Message ID,在partnership.xml中的设置将会覆盖全局设置。
默认的内容传输编码是binary
,能够使用partenership.xml中的content_transfer_encoding
属性覆盖默认值。
OPEN AS2自动支持入站消息压缩,若是要开启出站消息压缩,须要在partenership.xml中设置compression_type
属性,惟一支持的压缩/解压格式是ZLIB
,默认是不启用压缩的。
partener: CLINFLASH、CDEE2B
这里咱们在同一台机器上部署两个OPEN AS2实例,为了使配置互不影响,咱们将OPEN AS2的程序目录拷贝2份,分别为OpenAS2-01
、OpenAS2-02
。
进入OpenAS2-02,在config目录下生成密钥clinflash-pv.p12(keystore)、clinflash-pv.cer(public key).
../bin/gen_p12_key_par.sh clinflash-pv clinflash-pv SHA256 \
"CN=www.clinflash.net, OU=Clinflash, O=Clinflash, L=Shanghai, S=Shanghai, C=CN"
复制代码
config.xml
修改证书路径及密码
<certificates classname="org.openas2.cert.PKCS12CertificateFactory" filename="%home%/clinflash-pv.p12" password="123456" interval="300"/>
复制代码
发送轮询目录配置仅保留一条
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule" outboxdir="$properties.storageBaseDir$/toCDEE2B/" errordir="$properties.storageBaseDir$/toCDEE2B/error" interval="5" defaults="sender.as2_id=CLINFLASH, receiver.as2_id=CDEE2B" sendfilename="true" mimetype="application/EDI-X12"/>
复制代码
其它配置无需修改。
partenership.xml
其中,as2_url须要与接收方AS2接收消息的host、port一致,若是接收方也是OPEN AS2,配置在config.xml中的AS2ReceiverModule模块。
<partnerships>
<partner name="CLINFLASH" as2_id="CLINFLASH" x509_alias="clinflash-pv" email="xxx@xxx.com"/>
<partner name="CDEE2B" as2_id="CDEE2B" x509_alias="cdee2b" email="xxx@xxx.com"/>
<partnership name="CLINFLASH-to-CDEE2B">
<sender name="CLINFLASH"/>
<receiver name="CDEE2B"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="binary"/>
<attribute name="compression_type" value="ZLIB"/>
<attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
<attribute name="as2_url" value="http://localhost:20080"/>
<attribute name="as2_mdn_to" value="any string"/>
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA256"/>
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="CDEE2B-to-CLINFLASH">
<sender name="CDEE2B"/>
<receiver name="CLINFLASH"/>
</partnership>
</partnerships>
复制代码
进入OpenAS2-02,在config目录下生成密钥cdee2b.p12(keystore)、cdee2b.cer(public key)
../bin/gen_p12_key_par.sh cdee2b cdee2b SHA256 \
"CN=www.cde.org.cn, OU=CDE, O=CDE, L=Beijing, S=Beijing, C=CN"
复制代码
config.xml
修改证书路径及密码
<certificates classname="org.openas2.cert.PKCS12CertificateFactory" filename="%home%/cdee2b.p12" password="123456" interval="300"/>
复制代码
发送轮询目录配置仅保留一条
<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule" outboxdir="$properties.storageBaseDir$/toCLINFLASH/" errordir="$properties.storageBaseDir$/toCLINFLASH/error" interval="5" defaults="sender.as2_id=CDEE2B, receiver.as2_id=CLINFLASH" sendfilename="true" mimetype="application/EDI-X12"/>
复制代码
其它配置无需修改。
partenership.xml
<partnerships>
<partner name="CDEE2B" as2_id="CDEE2B" x509_alias="cdee2b" email="xxx@xxx.com"/>
<partner name="CLINFLASH" as2_id="CLINFLASH" x509_alias="clinflash-pv" email="xxx@xxx.com"/>
<partnership name="CDEE2B-to-CLINFLASH">
<sender name="CDEE2B"/>
<receiver name="CLINFLASH"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="binary"/>
<attribute name="compression_type" value="ZLIB"/>
<attribute name="subject" value="File $attributes.filename$ sent from $sender.name$ to $receiver.name$"/>
<attribute name="as2_url" value="http://localhost:10080"/>
<attribute name="as2_mdn_to" value="any string"/>
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, $attribute.sign$"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA256"/>
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="CLINFLASH-to-CDEE2B">
<sender name="CLINFLASH"/>
<receiver name="CDEE2B"/>
</partnership>
</partnerships>
复制代码
交换密钥
互相将公钥发送给对方,并导入到密钥库。
导入公钥的命令以下
cert import <alias> <path+filename> <keystore password>
复制代码
OPEN AS2也提供了快捷的脚本import_public_cert.sh
,使用方法以下
import_public_cert.sh <src certificate> <target keystore> <cert alias>
复制代码
测试
分别启动OpenAS2-0一、OpenAS2-02,但启动第二个实例发现链接数据库所用的9092端口被占用了,这时将其中一个的config.xml中的9092改成其它端口便可。
在OpenAS2-01/data/toCDEE2B/目录下添加任意文件
echo "test openas2..." > test.xml
复制代码
立刻会看到Message sent and MDN received successfully
提示发送成功并接收到回执。
此时进入OpenAS2-02/data/CLINFLASH-CDEE2B/inbox目,发现刚才接收到的文件test.xml-OPENAS2-28062019002300+0800-5bf115dd-b9f6-4fd2-b5ce-c6db19d2b435@CLINFLASH_CDEE2B
。
至此,从CLINFLASH向CDEE2B传输测试成功;一样的,CDEE2B向CLINFLASH传输文件测试下来也没有问题。
到目前位置,关于OPEN AS2基本的使用上面以及都有说起,但OPEN AS2的功能远不止这些,如日志、数据库记录、邮件服务等细节问题还须要根据实际项目须要进一步实践。