This library is a fork of OpenAS2 which did not release updates since 2010 (as per August 2015 they are on GitHub at https://github.com/OpenAS2/OpenAs2App). I than split the project into a common library part (this project) and a server part which contains a stand alone server. This project also contains a simple AS2 client which can be used to send messages to other AS2 servers.
This project is used in my following other projects:
- as2-server - a stand alone AS2 server operating on a socket layer.
- as2-peppol-client - a stand alone AS2 client that is capable of sending PEPPOL compliant e-Procurement documents.
- as2-peppol-servlet - integration into the Servlet specifications and for use with the PEPPOL transport infrastructure including SBDH (Standard Business Document Header) handling.
- as2-peppol-server - a stand alone Servlet based server to receive PEPPOL AS2 messages.
as2-lib is licensed under the FreeBSD License.
as2-partnership-mongodb is licensed under the Apache 2 license.
as2-servlet is licensed under the Apache 2 license.
as2-demo-webapp is licensed under the Apache 2 license.
News and noteworthy
- v4.2.0 - work in progress
- Added support for large file transmission (using Apache HttpClient) - thanks to @zharpaz for the PRs :D
- AS2 client now has the possibility to not request an MDN at all
- It's now possible to use a different Security Provider besides BouncyCastle (see #52)
- Added workaround for bug in
- Using the correct signing algorithm for the MIC, according to the partnership definitions (see #50)
- Added new subproject
as2-demo-webappto provide a simple to use stub for a web application receiving AS2 messages (see #36)
- Loading of keystores now also works from classpath by default. Based on https://github.com/phax/as2-peppol-server/issues/2
AS2ClientRequest.setData (File)in favour of
AS2ClientRequest.setData (File, Charset)(see #45)
Content-Typehandling was improved all over the place to avoid exception in case of error (see #33)
- v4.1.1 - 2018-07-27 - please use only with ph-commons 9.1.4 or newer
- The existence of just the header
Disposition-Notification-Todoes not trigger MDN sending anymore (see #42)
- Fixed overwriting of existing
Content-Transfer-Encodingwhen receiving messages.
- Partnership attribute
blockerrormdnis now only evaluated for MDNs that are created based on errors
- MDNs now also use the partner attribute
- The existence of just the header
- v4.1.0 - 2018-06-20
- The random parameters class now supports creating random values that are longer than 10 characters
- Fixed OSGI ServiceProvider configuration
- Added support for new encryption algorithms (see #38)
- Added new system property
AS2.httpDumpDirectoryOutgoingto easily dump outgoing transmissions
- Renamed system property for dumping incoming HTTP transmissions from
AS2.httpDumpDirectoryIncomingto avoid confusion. The old name can still be used but emits a warning.
MessageFileModulenow got a new attribute
charsetto define the charset to be used to dump the information.
- Requires ph-commons 9.1.2
- v4.0.2 - 2018-04-05
- improved client configurability and customizability
- Switching back to preferring BC PKCS12 key store, because JDK PKCS 12 key store is partially case insensitive
- v4.0.1 - 2018-03-27
- Updated to BouncyCastle 1.59
- When using the non-servlet version, the values for the
destination_ipfields were fixed (see https://github.com/phax/as2-server/issues/20)
- v4.0.0 - 2018-01-06
- Updated to ph-commons 9.0.0
- Updated to BouncyCastle 1.58
- Fixed crypto algorithm case sensitivity issue on sending (issue #32)
- Changed internally from
java.time.LocalDateTime- so all the Date parameters must be changed from
- The certificate factory
com.helger.as2lib.cert.PKCS12CertificateFactorywas deprecated in favor of the more generic
com.helger.as2lib.cert.CertificateFactorythat handles arbitrary keystore types (like JKS).
- v3.1.0 - 2017-07-27
- AS2 client can now handle custom HTTP headers
- Reworked dumping API to create new dumpers per request
- Dumping API was moved into a separate package.
- v3.0.4 - 2017-06-19
- AS2 client allows different content type even if text source is used
- AS2 client allows to specify Content-Transfer-Encoding
- Updated to BouncyCastle 1.57
- The receiving modules got a new attribute
errorstorebodyto indicate whether the body of a failed message should also be stored or not (default is
- The receiving modules
errordirdirectory can now handle parameters (date and msg)
- AS2 client can now request and asynchronous MDN (issue #31)
- v3.0.3 - 2017-01-24
- Binds to ph-commons 8.6.x
- Binds to ph-web 8.7.0
- Updated to BouncyCastle 1.56
- v3.0.2 - 2016-11-28
- Improved signature validation certificate selection (#28) - thanks @rklyne
- Made connect and read timeout configurable in
- v3.0.1 - 2016-09-27
- Made incoming HTTP request dumping customizable (issue #26)
- v3.0.0 - 2016-08-21
- JDK 8 is now required
- Using ph-commons 8.4.x
- v2.2.8 - 2016-05-09
- Improved AS2 client https customization and API
- v2.2.7 - 2016-04-27
- Added per partnership attribute
rfc3851_micalgsto determine to use RFC 3851 MIC algorithm names instead of the default RFC 5751 MIC algorithm names (issue #18)
- Fixed problem with special character escaping in MDN context (issue #19)
- Added per partnership attribute
- v2.2.6 - 2016-03-02
- Added support for dumping HTTP requests when using
- Added support for dumping HTTP requests when using
- v2.2.5 - 2015-12-01
- Added a validity check so that expired certificates can no longer be used to sign, verify and encrypt messages. Decrypt is still possible.
- Added the possibility to disable the autosave of the
PKCS12CertificateFactoryusing the new boolean attribute
autosave. This can now also easily be set in the client settings. (issue #17)
- Fixed potential endless loop when a retry count was specified at a partnership (issue #16)
- v2.2.4 - 2015-11-11
- Fixed a minor issue where details of a ProcessingException were not passed into the MDN text
- v2.2.3 - 2015-10-22
- Improved API for handling MDN errors (as2-lib issue #11)
- The signature verification of messages sent without
Content-Transfer-Encodingwas fixed (as2-lib issue #12)
- Receiving a message for an unknown partnership now results in a correct error MDN (as2-server issue #16)
- The new sub-project
as2-servletis now contained
- v2.2.2 - 2015-10-19
- Updated to Bouncy Castle 1.53 (as2-lib issue #10)
- v2.2.1 - 2015-10-08
- Extended API and some debug logging added
- v2.2.0 - 2015-09-27
- added system properties (see below) for configuration and debugging purposes
- added new resender modules:
- added the following new partnership attributes:
content_transfer_encoding_receive[receiver side] to define a fixed
Content-Transfer-Encodingfor receiving, even if none is specified.
force_decrypt[receiver side] to force decryption of incoming messages even if the
Content-Typeheader claims the message is not encrypted (as a work-around for non spec-compliant senders)
disable_decrypt[receiver side] to disable decryption of incoming messages even if the
Content-Typeheader claims the message is encrypted (as a work-around for non spec-compliant senders)
force_verify[receiver side] to force signature validation of incoming messages even if the
Content-Typeheader claims the message is not signed (as a work-around for non spec-compliant senders)
disable_verify[receiver side] to disable signature verification of incoming messages even if the
Content-Typeheader claims the message is signed (as a work-around for non spec-compliant senders)
verify_use_cert_in_body_part[receiver side] to define whether a certificate passed in the signed MIME body part shall be used to verify the signature (when
true) or whether to always use the certificate provided in the partnership (when
false). If not set the value of the AS2 session is used.
disable_decompress[receiver side] to disable decompression of incoming messages even if the
Content-Typeheader claims the message is compressed (as a work-around for non spec-compliant senders)
sign_include_cert_in_body_part[sender side] to determine whether the certificate used for signing should be included in the signed content part (when
true) or not (when
false). The default value is
- Added the sub-project
as2-partnership-mongodb- thanks to @jochenberger for contributing it
- Version 2.1.0 - 2015-08-20
- fixes a problem that implicitly SHA-1 was always used for signing, no matter what you specify
- compression according to RFC 5402 is now supported so that this is no fully AS2 1.1 compatible
Add the following to your
pom.xml to use this artifact:
<dependency> <groupId>com.helger</groupId> <artifactId>as2-lib</artifactId> <version>4.1.1</version> </dependency>
For the MongoDB partnership factory, add the following to your
<dependency> <groupId>com.helger</groupId> <artifactId>as2-partnership-mongodb</artifactId> <version>4.1.1</version> </dependency>
For the receive servlet, add the following to your
<dependency> <groupId>com.helger</groupId> <artifactId>as2-servlet</artifactId> <version>4.1.1</version> </dependency>
This project is build with Apache Maven 3.x. Simply call
mvn clean install and you will end up with a JAR file in the
as2-lib/target directory. This library is used as the basis for the standalone as2-server which is an pure Java Open Source AS2 server.
All projects require Java 1.8 for building and running.
as2-partnership-mongodb sub-project downloads an embedded MongoDB from the official web site and extracts it for testing. If this makes problems specify the
-DskipTests=true commandline parameter when invoking Maven.
This library manages the package
com.helger.as2lib and all sub-packages:
- com.helger.as2lib - contains the global AS2 settings
- com.helger.as2lib.cert - contains the certificate factory
- com.helger.as2lib.client - contains the AS2 client for sending messages
- com.helger.as2lib.crypto - contains the BouncyCastle crypto code for signing, verification, encryption and decryption of messages
- com.helger.as2lib.disposition - contains code to handle content disposition
- com.helger.as2lib.exception - contains basic exception classes
- com.helger.as2lib.message - contains the main message and MDN classes
- com.helger.as2lib.params - generic code that allows for parameterization of certain message related configuration items
- com.helger.as2lib.partner - contains the partnership and factory code
- com.helger.as2lib.partner.xml - contains the XML based version of a partnership factory
- com.helger.as2lib.processor - contains the basic building blocks for processing of messages
- com.helger.as2lib.processor.module - contains the basic classes for "active" modules (modules that can be started and stopped)
- com.helger.as2lib.processor.receiver - module for receiving messages
- com.helger.as2lib.processor.receiver.net - module for receiving messages from Sockets
- com.helger.as2lib.processor.resender - modules for re-sending messages
- com.helger.as2lib.processor.sender - module for sending messages
- com.helger.as2lib.processor.storage - module for storing messages
- com.helger.as2lib.util - contains utility classes used in several places in this library or in derived projects
- com.helger.as2lib.util.cert - utility classes for certificate handling
- com.helger.as2lib.util.http - utility classes for HTTP connection handling
- com.helger.as2lib.util.javamail - utility classes for javax.mail handling
The following system properties are available for global customization
AS2.useSecureRandom- since v2.2.0 - determine whether the Java
SecureRandomshould be used or not. On some Unix/Linux systems the initialization of
SecureRandomtakes forever and this is how you easily disable it (
AS2.httpDumpDirectoryIncoming- since v4.1.0 (old name
AS2.httpDumpDirectorysince v2.2.0) - if this system property is defined, all incoming HTTP traffic is dumped "as is" into the specified directory (e.g.
-DAS2.httpDumpDirectoryIncoming=/var/dump/as2-http-incoming). The filename starts with "as2-incoming-", contains the current timestamp as milliseconds, followed by a dash and a unique index and finally has the extension ".http"
AS2.dumpDecryptedDirectory- since v2.2.0 - if this system property is defined, all incoming decrypted MIME parts are dumped "as is" into the specified directory (e.g.
-DAS2.dumpDecryptedDirectory=/var/dump/as2-decrypted). The filename starts with "as2-decrypted-", contains the current timestamp as milliseconds, followed by a dash and a unique index and finally has the extension ".part"
AS2.httpDumpDirectoryOutgoing- since v4.1.0 - if this system property is defined, all outgoing HTTP traffic is dumped "as is" into the specified directory (e.g.
-DAS2.httpDumpDirectoryOutgoing=/var/dump/as2-http-outgoing). The filename starts with "as2-outgoing-", contains the current timestamp as milliseconds, followed by a dash and a unique index and finally has the extension ".http".
as2-lib ships with a powerful client to send AS2 messages. It can easily be embedded in standalone Java applications and does not require any server part. All the necessary classes are in the package
For a quick start look at https://github.com/phax/as2-lib/blob/master/as2-lib/src/test/java/com/helger/as2lib/supplementary/main/MainSendToMendelsonTestServer.java as a working example on how to send an arbitrary file to the Mendelson test server.
The client basically separates between per-partnership settings (class
AS2ClientSettings) and the content to be transmitted (class
AS2ClientRequest). The glue that holds all of this together is the class
AS2Client that takes the settings and the request, adds the possibility to define an HTTP(S) proxy server, and does the synchronous sending. The settings and the main client are thought to be reusable, whereas the request data is to be changed for every request.
The response of a client request is defined by class
AS2ClientResponse. It stores the original message ID, the received MDN/the occurred exception and the execution duration. The interpretation of the received MDN is up to the user.
This is an implementation of interface
com.helger.as2lib.partner.IPartnershipFactory from as2-lib using MongoDB as the backend.
Tests are done with Groovy and Spock.
This sub-project is licensed under the Apache 2 License.
A stand alone servlet that takes AS2 requests and handles them via a
This sub-project is licensed under the Apache 2 License.
To use this project you have to do the following - all described in more detail below:
- Add the
as2-servletproject as a dependency to your project - e.g. via Maven
- Modify your
WEB-INF/web.xmlfile so that it references the
- Create an AS2 configuration file and store it in a folder that is fully writable to your project. The details of the configuration files are described below.
- Create a key store file (e.g.) called
server-certs.p12located in the same folder as the configuration file. The keystore type must be
PKCS12. It must at least contain your private key. The path and the password of the keystore must be set in the AS2 configuration file.
<servlet> <servlet-name>AS2ReceiveServlet</servlet-name> <servlet-class>com.helger.as2servlet.AS2ReceiveServlet</servlet-class> <init-param> <param-name>as2-servlet-config-filename</param-name> <param-value>as2-server-data/as2-server-config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>AS2ReceiveServlet</servlet-name> <url-pattern>/as2/*</url-pattern> </servlet-mapping>
As you can see, a configuration file called
as2-server-data/as2-server-config.xml is referenced as an
init-param of the servlet. The name of the
init-param must be
as2-servlet-config-filename. Please make sure to insert the correct absolute path to the configuration file inside the
In this example the servlet is mapped to the path
/as2 meaning that messages must be targeted to this URL (e.g.
AS2 Configuration file
A special XML configuration file must be used to configure the AS2 handling. It contains:
- a reference to the keystore to be used (in element
- a reference to a partnership factory (storing the exchange combinations) (in element
- a list of modules that are executed when a message is received (in elements
Within a configuration file, the macro
%home% is replaced with the parent directory of the configuration file. This replacement happens only when a value starts with
Complete example configuration file:
<?xml version="1.0" encoding="utf-8"?> <openas2> <!-- [required] The keystore to be used (since v4) --> <certificates classname="com.helger.as2lib.cert.CertificateFactory" type="pkcs12" filename="%home%/server-certs.p12" password="mypassword" /> <!-- [required] The keystore to be used (prior to v4) --> <!-- <certificates classname="com.helger.as2lib.cert.PKCS12CertificateFactory" filename="%home%/server-certs.p12" password="mypassword" /> --> <!-- [required] The pro-forma partnership factory --> <partnerships classname="com.helger.as2servlet.util.AS2ServletPartnershipFactory" filename="%home%/server-partnerships.xml" disablebackup="true" /> <!-- [required] the processing queue --> <processor classname="com.helger.as2lib.processor.DefaultMessageProcessor" pendingMDN="%home%/pendingMDN" pendingMDNinfo="%home%/pendinginfoMDN"> <!-- [optional] Store sent MDNs to a file Note: "charset" attribute was added in v4.1.0 --> <module classname="com.helger.as2lib.processor.storage.MDNFileModule" filename="%home%/mdn/$date.uuuu$/$date.MM$/$mdn.msg.sender.as2_id$-$mdn.msg.receiver.as2_id$-$mdn.msg.headers.message-id$" protocol="as2" tempdir="%home%/temp" charset="utf-8" /> <!-- [optional] Store received messages and headers to a file Note: "charset" attribute was added in v4.1.0 --> <module classname="com.helger.as2lib.processor.storage.MessageFileModule" filename="%home%/inbox/$date.uuuu$/$date.MM$/$msg.sender.as2_id$-$msg.receiver.as2_id$-$msg.headers.message-id$" header="%home%/inbox/msgheaders/$date.uuuu$/$date.MM$/$msg.sender.as2_id$-$msg.receiver.as2_id$-$msg.headers.message-id$" protocol="as2" tempdir="%home%/temp" charset="utf-8" /> <!-- [required] The main receiver module that performs the message parsing. This module also sends synchronous MDNs back. Note: the port attribute is required but can be ignored in our case! Note: the 'errordir' attribute allows parameters since v3.0.4 only! Note: the 'errorstorebody' attribute was added with v3.0.4! --> <module classname="com.helger.as2servlet.util.AS2ServletReceiverModule" port="10080" errordir="%home%/inbox/error/$date.uuuu$/$date.MM$" errorformat="$msg.sender.as2_id$, $msg.receiver.as2_id$, $msg.headers.message-id$" errorstorebody="false"/> <!-- To process the documents further than just storing them to disk, implement class AbstractProcessorModule and register the module here. See the phax/as2-peppol-servlet project on how to handle e.g. SBDH documents --> </processor> </openas2>