OPEN AS2使用入门

AS2协议(Applicability Statement 2)是在互联网上安全可靠地传输数据的标准规范。它通过使用数字证书、加密机制保障传输数据的安全性。

OpenAS2 是用 Java 实现 AS2 的开源项目, 基于FreeBSD开源协议,OpenAS2 使您能够在交易伙伴之间传送和接收 EDI-X12、EDIFACT、XML 或二进制形式的 AS2 消息。

1.下载安装

Open AS2 下载地址:https://sourceforge.net/projects/openas2

下载解压,无需安装即可运行,目录结构如下:

.
├── OpenAS2HowTo.pdf
├── RELEASE-NOTES.md
├── bin
├── changes.txt
├── config
├── lib
└── resources

2.启动测试

在执行脚本之前,需要确认的是系统中已经设置了JAVA_HOME环境变量。

给启动脚本添加执行权限

chmod +x ./bin/start-openas2.sh

启动OPEN AS2

./bin/start-openas2.sh

如果一切正常的话会看到以下提示

FINE OpenAS2Server: OpenAS2 Server v2.9.0 started.

3.生成密钥

$ ./gen_p12_key_par.sh clinflash-pv clinflash-pv SHA256 \
"CN=www.clinflash.com, 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

4.配置说明

配置文件位于config目录,其中各个文件有不同作用

  • config.xml


    主要配置文件,包含全局属性、密钥证书、伙伴配置文件、日志、发送文件目录、接收文件目录等许多信息的相关配置。
  • partnerships.xml


    用于配置EDI伙伴以及伙伴关系。
  • as2_certs.p12


    用于保护伙伴信息的PKCS12签名文件,这是默认的文件名,可以在config.xml指定自定义的的文件名。
  • commands.xml


    此文件列出了OPEN AS2支持的命令,一般情况下不要去更改这个文件内容。

另外,config.xml文件中的配置如果发生更改需要重启应用才会生效,而其它文件配置发生更改会自动刷新。

4.1 config.xml应用配置

4.1.1 属性配置

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">
</>
4.1.2 证书配置
<certificates classname="org.openas2.cert.PKCS12CertificateFactory"
        filename="%home%/as2_certs.p12"
        password="testas2"
        interval="300"/>

%home%表示当前目录,也就是config目录,filenamepassword的属性值需要改成我们的keystore文件和密码。

4.1.3 伙伴关系文件配置

这里仅仅定义了伙伴关系文件的位置,详细的配置信息在这个文件中。

<partnerships classname="org.openas2.partner.XMLPartnershipFactory"
        filename="%home%/partnerships.xml"
        interval="120"/>
4.1.4 发送文件配置

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"
4.1.5 消息跟踪

从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="'"
        />
4.1.6 重试配置

如果消息传输出错,系统会自动无限重试,但可以配置重试次数。

config.xml中的配置的重试次数会被partnerships.xml中配置的重试次数覆盖。

<module classname="org.openas2.processor.sender.AS2SenderModule" retries="5"/>
<module classname="org.openas2.processor.sender.MDNSenderModule" retries="3"/>
4.1.7 其它配置

另外还有一些其它配置,如文件名解析、代理服务器、健康检查等,可以查看OPEN AS2的使用说明 OpenAS2HowTo.pdf

4.2 partnerships.xml伙伴配置

partnerships.xml中配置了信息交换伙伴的所有信息

4.2.1 <partner> 定义了信息交换的贸易伙伴信息



name:贸易伙伴的名称;


as2_id:贸易伙伴之间确认身份的标识,同时也被通用发送文件轮询模块用来解析文件名;


x509_alias:证书别名,需要与密钥证书设置的别名一致。

4.2.2 <partnership> 定义了2个贸易伙伴之间的关系



sender:需要与发送方<partner>中的name属性值一致


receive:需要与接收方<partner>中的name属性值一致


sign:AS2报文签名算法,支持md2, md5, sha1, sha224, sha256, sha384, sha512


encrypt:AS2报文加密算法,支持3des, cast5, rc2_cbc, aes128, aes192, aes256

4.2.3 伙伴关系配置示例

下面的示例是自己公司和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>

4.2.4 AS2 Message ID

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中的设置将会覆盖全局设置。

4.2.5 内容传输编码

默认的内容传输编码是binary,可以使用partenership.xml中的content_transfer_encoding属性覆盖默认值。

4.2.6 消息压缩

OPEN AS2自动支持入站消息压缩,如果要开启出站消息压缩,需要在partenership.xml中设置compression_type属性,唯一支持的压缩/解压格式是ZLIB,默认是不启用压缩的。

5.传输测试

partener: CLINFLASH、CDEE2B

这里我们在同一台机器上部署两个OPEN AS2实例,为了使配置互不影响,我们将OPEN AS2的程序目录拷贝2份,分别为OpenAS2-01OpenAS2-02

5.1 Partener 1 - CLINFLASH

进入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.com, 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>

5.2 Partener 2 - CDEE2B

进入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-01、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传输文件测试下来也没有问题。

6.总结

到目前位置,关于OPEN AS2基本的使用上面已经都有提及,但OPEN AS2的功能远不止这些,如日志、数据库记录、邮件服务等细节问题还需要根据实际项目需要进一步实践。

本文转自我个人的掘金博客,但由于掘金没有文章目录、分类功能,管理文章非常不方便,不打算继续使用了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容