[轉貼]Manage business documents with OpenAS2 on Fedora
Manage business documents with OpenAS2 on Fedora
Business documents often require special handling. Enter Electronic Document Interchange, or EDI. EDI is more than simply transferring files using email or http (or ftp), because these are documents like orders and invoices. When you send an invoice, you want to be sure that:
1. It goes to the right destination, and is not intercepted by competitors. 2. Your invoice cannot be forged by a 3rd party. 3. Your customer can’t claim in court that they never got the invoice.
The first two goals can be accomplished by HTTPS or email with S/MIME, and in some situations, a simple HTTPS POST to a web API is sufficient. What EDI adds is the last part.
This article does not cover the messy topic of formats for the files exchanged. Even when using a standardized format like ANSI or EDIFACT, it is ultimately up to the business partners. It is not uncommon for business partners to use an ad-hoc CSV file format. This article shows you how to configure Fedora to send and receive in an EDI setup.
Centralized EDI
The traditional solution is to use a Value Added Network, or VAN. The VAN is a central hub that transfers documents between their customers. Most importantly, it keeps a secure record of the documents exchanged that can be used as evidence in disputes. The VAN can use different transfer protocols for each of its customers
AS Protocols and MDN
The AS protocols are a specification for adding a digital signature with optional encryption to an electronic document. What it adds over HTTPS or S/MIME is the Message Disposition Notification, or MDN. The MDN is a signed and dated response that says, in essence, “We got your invoice.” It uses a secure hash to identify the specific document received. This addresses point #3 without involving a third party.
The AS2 protocol uses HTTP or HTTPS for transport. Other AS protocols target FTP and SMTP. AS2 is used by companies big and small to avoid depending on (and paying) a VAN.
OpenAS2
OpenAS2 is an open source Java implemention of the AS2 protocol. It is available in Fedora since 28, and installed with:
$ sudo dnf install openas2 $ cd /etc/openas2
Configuration is done with a text editor, and the config files are in XML. The first order of business before starting OpenAS2 is to change the factory passwords.
Edit /etc/openas2/config.xml and search for ChangeMe. Change those passwords. The default password on the certificate store is testas2, but that doesn’t matter much as anyone who can read the certificate store can read config.xml and get the password.
What to share with AS2 partners
There are 3 things you will exchange with an AS2 peer.
AS2 ID
Don’t bother looking up the official AS2 standard for legal AS2 IDs. While OpenAS2 implements the standard, your partners will likely be using a proprietary product which doesn’t. While AS2 allows much longer IDs, many implementations break with more than 16 characters. Using otherwise legal AS2 ID chars like ‘:’ that can appear as path separators on a proprietary OS is also a problem. Restrict your AS2 ID to upper and lower case alpha, digits, and ‘_’ with no more than 16 characters.
SSL certificate
For real use, you will want to generate a certificate with SHA256 and RSA. OpenAS2 ships with two factory certs to play with. Don’t use these for anything real, obviously. The certificate file is in PKCS12 format. Java ships with keytool which can maintain your PKCS12 “keystore,” as Java calls it. This article skips using openssl to generate keys and certificates. Simply note that sudo keytool -list -keystore as2_certs.p12 will list the two factory practice certs.
AS2 URL
This is an HTTP URL that will access your OpenAS2 instance. HTTPS is also supported, but is redundant. To use it you have to uncomment the https module configuration in config.xml, and supply a certificate signed by a public CA. This requires another article and is entirely unnecessary here.
By default, OpenAS2 listens on 10080 for HTTP and 10443 for HTTPS. OpenAS2 can talk to itself, so it ships with two partnerships using http://localhost:10080 as the AS2 URL. If you don’t find this a convincing demo, and can install a second instance (on a VM, for instance), you can use private IPs for the AS2 URLs. Or install Cjdns to get IPv6 mesh addresses that can be used anywhere, resulting in AS2 URLs like http://[fcbf:fc54:e597:7354:8250:2b2e:95e6:d6ba]:10080.
Most businesses will also want a list of IPs to add to their firewall. This is actually bad practice. An AS2 server has the same security risk as a web server, meaning you should isolate it in a VM or container. Also, the difficulty of keeping mutual lists of IPs up to date grows with the list of partners. The AS2 server rejects requests not signed by a configured partner.
OpenAS2 Partners
With that in mind, open partnerships.xml in your editor. At the top is a list of “partners.” Each partner has a name (referenced by the partnerships below as “sender” or “receiver”), AS2 ID, certificate, and email. You need a partner definition for yourself and those you exchange documents with. You can define multiple partners for yourself. OpenAS2 ships with two partners, OpenAS2A and OpenAS2B, which you’ll use to send a test document.
OpenAS2 Partnerships
Next is a list of “partnerships,” one for each direction. Each partnership configuration includes the sender, receiver, and the AS2 URL used to send the documents. By default, partnerships use synchronous MDN. The MDN is returned on the same HTTP transaction. You could uncomment the as2_receipt_option for asynchronous MDN, which is sent some time later. Use synchronous MDN whenever possible, as tracking pending MDNs adds complexity to your application.
The other partnership options select encryption, signature hash, and other protocol options. A fully implemented AS2 receiver can handle any combination of options, but AS2 partners may have incomplete implementations or policy requirements. For example, DES3 is a comparatively weak encryption algorithm, and may not be acceptable. It is the default because it is almost universally implemented.
If you went to the trouble to set up a second physical or virtual machine for this test, designate one as OpenAS2A and the other as OpenAS2B. Modify the as2_url on the OpenAS2A-to-OpenAS2B partnership to use the IP (or hostname) of OpenAS2B, and vice versa for the OpenAS2B-to-OpenAS2A partnership. Unless they are using the FedoraWorkstation firewall profile, on both machines you’ll need:
Now start the openas2 service (on both machines if needed):
# sudo systemctl start openas2
Resetting the MDN password
This initializes the MDN log database with the factory password, not the one you changed it to. This is a packaging bug to be fixed in the next release. To avoid frustration, here’s how to change the h2 database password:
alter user sa set password '$2'; exit EOF DONE $ sudo sh h2passwd ChangeMe yournewpasswordsetabove $ sudo systemctl start openas2
Testing the setup
With that out of the way, let’s send a document. Assuming you are on OpenAS2A machine:
$ cat >testdoc <<'DONE' This is not a real EDI format, but is nevertheless a document. DONE $ sudo chown openas2 testdoc $ sudo mv testdoc /var/spool/openas2/toOpenAS2B $ sudo journalctl -f -u openas2 ... log output of sending file, Control-C to stop following log ^C
OpenAS2 does not send a document until it is writable by the openas2 user or group. As a consequence, your actual business application will copy, or generate in place, the document. Then it changes the group or permissions to send it on its way, to avoid sending a partial document.
Now, on the OpenAS2B machine, /var/spool/openas2/OpenAS2A_OID-OpenAS2B_OID/inbox shows the message received. That should get you started!
[轉貼]Getting Started With AS2 Protocol Using AS2Gateway and OpenAS2
Getting Started With AS2 Protocol Using AS2Gateway and OpenAS2
Most of the large retail providers and consumer product suppliers such as Walmart, Amazon, Morgan Foods, etc. have decided to go with AS2 protocol in the last few years. Based on this trend, all of their suppliers are asked to send their invoices, purchase orders, and other B2B trading messages over AS2. Because of that, the trend for usage of AS2 has been significantly increased over the last couple of years. In this blog, I’m going to explain how to get started with AS2 protocol and how you send and receive AS2 messages using two software applications which provide AS2 capabilities.
What Is AS2?
In simple terms, the Applicability Statement 2 or AS2 specification defines a mechanism for secure and reliable transfer of structured business data over the Internet. In contrast to other traditional B2B trading protocols, AS2 offers a secure, efficient, and simple to use trading environment without a need for proprietary devices, software, or expensive private networks or value added networks. If you are new to AS2 protocol, I highly recommend you read this description of AS2 protocol before going to use it in your production requirements. It describes what AS2 is, why we need AS2, and its key benefits in simple terms, and you don’t have to have a technical background to understand it. If you have some technical background and you want to know how the protocol operates over the HTTP/S protocol, you can refer to this and get a better understanding of the implementation of the AS2 protocol.
There are a few software applications (on-premise and SaaS) which provide AS2 capability. For this exercise, I have used AS2Gateway and OpenAS2 to explain how to configure these two applications to send messages back and forth.
What Is OpenAS2?
OpenAS2 is a Java-based implementation of the AS2 standard which supports XML file-based configuration — user interface configuration is not yet implemented, but it’s there on their roadmap. You can download OpenAS2 from the above location. Make sure you download the latest version to minimize the effect of already fixed issues.
What Is AS2Gateway?
AS2Gateway is a SaaS application which implements the AS2 specification while providing the ability to configure AS2 stations and trading partners from a nice and simple user interface. Compared to OpenAS2, it’s quite easy to configure AS2Gateway for your AS2 requirements - especially if you are a user who doesn’t have a good technical background and are not familiar with server type applications working without a graphical UI. You will understand the difference while reading this blog. Since it has a GUI, it provides additional utility functionalities for advanced requirements on AS2, such as certificate management, SFTP integration, and much more.
In this exercise, I’m using two hypothetical organizations — Company X and Company Y, which expect to send and receive AS2 messages back and forth based on their B2B trading requirements. Company names will be important here, because I’m going to use AS2 identifiers based on the company name; for Company X, the AS2 identifier will be company-x-as2-id and for Company Y, it company-y-as2-id. Company X uses OpenAS2 as the AS2 software, while Company Y uses AS2Gateway as its AS2 software.
First, I’ll explain how Company X should configure its AS2 Station and trading partners in OpenAS2 and then explain the same on the AS2Gateway.
Set Up OpenAS2
First, you need to install OpenAS2 on your machine.
Installation
You just need to download and extract the ZIP file for the installation. Once it’s extracted, you can start the AS2Server by executing the bin/start-openas2.sh file. Make sure scripts are executable.
Configuration
In OpenAS2, there isn’t a concept called AS2 Station. It identifies both station and partner as two different partners and configures their relationship as a partnership. There are two main configuration files that you need to focus on basic AS2 options.
The first one is the config/config.xml. In this file, you can configure modules for AS2 message handling. You need to configure a set of AS2DirectoryPollingModule modules to fetch files to send to different partner. For each partnership between two partners, you need to have an AS2DirectoryPollingModule module element to send files from one partner to another.
The second one is the config/partnership.xml. There you need to configure declarations of each partner and relationships between those declared partners. To declare partners, you should have a partner type XML element with partner name, partner AS2 ID, partner x509 alias (for certificate management) and email — just focus on partner name, AS2 ID, and partner alias.
All the relationships between each partner should be defined as a partnership XML element in the partnerships.xml file. This element represents one-way relationships between one partner to another. If you want to send messages in both sides, you have to configure two partnership XML elements.
The next main important thing is certificate management which is the tricky part. Here you have to import and export your certificates manually to/from your keystore. By default, it uses config/as2_certs.p12 as the keystore. You can configure the keystore path by changing the filename attribute of the certificates XML element in the config/config.xml file. In the default keystore, there are two keys for two default partners — openas2a and openas2b.
For keystore configuration, there are two things you have to do:
Import your trading partner’s certificate into keystore using a keystore managing software or keytool — you can get the certificate of the AS2Gateway station (company-y-as2-id) using “View partner configuration” option in the AS2Gateway.
Export certificate chain of the key of your side partner (or in other words, your AS2 station — in this example, this should be the key of AS2 station with AS2 ID company-x-as2-id) and use it to configure your trading partner at the other end (in this example, the other end is the Company Y).
To configure OpenAS2, as explained in the following section, you need information about the AS2Gateway side station. You can get this information from the “Partner Configuration” view of your AS2 station — AS2Station view -> View Partner Configuration. This view will have all the required information to configure AS2Gateway side station in some other AS2 server as a trading partner. Generally, users’ of the AS2Gateway will use this and send this information to their trading partners via Share Configuration option in the Partner Configuration view page
Configure OpenAS2 for the Example Use Case
From the OpenAS2 side, sending party would be AS2Station with AS2 ID — company-x-as2-id and receiving party AS2 ID should be company-y-as2-id.
1. For this, you first have to configure partnerships.xml file as below — from the Company X point for view, Company X is the AS2 station and Company Y is the trading partner.
<partnerships>
<partner name="CompanyXStation"
as2_id="company-x-as2-id"
x509_alias="company-x"
email="companyx@gmail.com"/>
<partner name="CompanyYPartner"
as2_id="company-y-as2-id"
x509_alias="company-y"
email="companyy@gmail.com"/>
<partnership name="CompanyXStation-to-CompanyYPartner"> <!-- partnership to send messages from CompanyXStation to CompanyYPartner -->
<sender name="CompanyXStation"/> <!-- sending party name-->
<receiver name="CompanyYPartner"/> <!-- receiving party name-->
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="8bit"/> <!-- content transfer encoding - seems like this is not working as expected -->
<attribute name="compression_type" value="ZLIB"/> <!-- compression type to used to compress AS2 message -->
<attribute name="subject" value="From OpenAS2A to OpenAS2B"/>
<attribute name="mdnsubject" value="Your requested MDN response from $receiver.as2_id$"/>
<attribute name="as2_url" value="http://service.beta.as2gateway.com:8280/service/as2-receiver"/>
<!-- This should be the CompanyXStation message receiving URL -->
<attribute name="as2_mdn_to" value="http://receipt.beta.as2gateway.com:8284/service/as2-async-mdn-receiver"/>
<!-- This should be the CompanyXStation MDN receiving URL -->
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha-256"/>
<!-- configure how do you want to get MDN - whether it should be signed or not etc.
This will be added directly to Disposition-Notification-Options transport header without any modification -->
<attribute name="encrypt" value="3DES"/> <!-- Encryption algorithm-->
<attribute name="sign" value="SHA1"/> <!-- Sign digest algorithm-->
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/> <!-- should verify the mic -->
<attribute name="no_set_transfer_encoding_for_signing" value="false"/>
<!-- better to go with the default values for the rest of the configurations -->
<attribute name="no_set_transfer_encoding_for_encryption" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="CompanyYPartner-to-CompanyXStation"> <!-- partnership to send messages from CompanyYPartner to CompanyXStation -->
<sender name="CompanyYPartner"/>
<receiver name="CompanyXStation"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="8bit"/>
<attribute name="subject" value="From OpenAS2B to OpenAS2A"/>
<attribute name="as2_url" value="http://my-public-ip:10080"/>
<!-- AS2 message receiving URL at the OpenAS2 side. IP of this URL should be replaced with your public IP.
This IP should be publically reachble. If you are using default configuration, then use above IP together with your IP -->
<attribute name="as2_mdn_to" value="http://my-public-ip:10081"/>
<!-- AS2 message receiving URL at the OpenAS2 side. IP of this URL should be replaced with your public IP.
This IP should be publically reachble. If you are using default configuration, then use above IP together with your IP -->
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha256"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA256"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
<attribute name="no_set_transfer_encoding_for_signing" value="false"/>
<attribute name="no_set_transfer_encoding_for_encryption" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
</partnerships>
2. Next, you need to configure config/config.xml file for file polling configurations — OpenAS2 gets input files (to send out as an AS2 message), by polling directories configured from following XML elements.
<partnerships>
<partner name="CompanyXStation"
as2_id="company-x-as2-id"
x509_alias="company-x"
email="companyx@gmail.com"/>
<partner name="CompanyYPartner"
as2_id="company-y-as2-id"
x509_alias="company-y"
email="companyy@gmail.com"/>
<partnership name="CompanyXStation-to-CompanyYPartner">
<!-- partnership to send messages from CompanyXStation to CompanyYPartner -->
<sender name="CompanyXStation"/> <!-- sending party name-->
<receiver name="CompanyYPartner"/> <!-- receiving party name-->
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="8bit"/>
<!-- content transfer encoding - seems like this is not working as expected -->
<attribute name="compression_type" value="ZLIB"/>
<!-- compression type to used to compress AS2 message -->
<attribute name="subject" value="From OpenAS2A to OpenAS2B"/>
<attribute name="mdnsubject" value="Your requested MDN response from $receiver.as2_id$"/>
<attribute name="as2_url" value="http://service.beta.as2gateway.com:8280/service/as2-receiver"/>
<!-- This should be the CompanyXStation message receiving URL -->
<attribute name="as2_mdn_to" value="http://receipt.beta.as2gateway.com:8284/service/as2-async-mdn-receiver"/>
<!-- This should be the CompanyXStation MDN receiving URL -->
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha-256"/>
<!-- configure how do you want to get MDN - whether it should be signed or not etc.
This will be added directly to Disposition-Notification-Options transport header without any modification -->
<attribute name="encrypt" value="3DES"/> <!-- Encryption algorithm-->
<attribute name="sign" value="SHA1"/> <!-- Sign digest algorithm-->
<attribute name="resend_max_retries" value="3"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/> <!-- should verify the mic -->
<attribute name="no_set_transfer_encoding_for_signing" value="false"/>
<!-- better to go with the default values for the rest of the configurations -->
<attribute name="no_set_transfer_encoding_for_encryption" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
<partnership name="CompanyYPartner-to-CompanyXStation"> <!-- partnership to send messages from CompanyYPartner to CompanyXStation -->
<sender name="CompanyYPartner"/>
<receiver name="CompanyXStation"/>
<attribute name="protocol" value="as2"/>
<attribute name="content_transfer_encoding" value="8bit"/>
<attribute name="subject" value="From OpenAS2B to OpenAS2A"/>
<attribute name="as2_url" value="http://my-public-ip:10080"/>
<!-- AS2 message receiving URL at the OpenAS2 side. IP of this URL should be replaced with your public IP.
This IP should be publically reachble. If you are using default configuration, then use above IP together with your IP -->
<attribute name="as2_mdn_to" value="http://my-public-ip:10081"/>
<!-- AS2 message receiving URL at the OpenAS2 side. IP of this URL should be replaced with your public IP.
This IP should be publically reachble. If you are using default configuration, then use above IP together with your IP -->
<attribute name="as2_mdn_options" value="signed-receipt-protocol=optional, pkcs7-signature; signed-receipt-micalg=optional, sha256"/>
<attribute name="encrypt" value="3DES"/>
<attribute name="sign" value="SHA256"/>
<attribute name="prevent_canonicalization_for_mic" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
<attribute name="no_set_transfer_encoding_for_signing" value="false"/>
<attribute name="no_set_transfer_encoding_for_encryption" value="false"/>
<attribute name="rename_digest_to_old_name" value="false"/>
<attribute name="remove_cms_algorithm_protection_attrib" value="false"/>
</partnership>
</partnerships>
3. Then you have to configure certificates and your keystore. For that, you first have to create a key pair for your Company-X side station. You can easily do that using a tool like Portacle. Since we have configured CompanyXStaion partner’s x509 alias as company-x, you have to give the entry name/alias for the key pair that you’re going to create for your Company-X.
4. Then you can export your OpenAS2 station’s certificate chain, as shown in the below screenshot. You just have to select the correct key and export the certificate chain via keystore management utility — Portacle.
5. Then, you have to import your CompanyYPartner’s certificate to your OpenAS2 side trust store. For that, you have to get this from the Company-Y side. In this case, you can get this certificate from the AS2Gateway.
With this, you are done with the OpenAS2 side configuration.
Set Up the AS2 Gateway
For AS2Gateway, you just have to sign up as a free user and get an evaluation period of one month with the exact same features, like a premium/paid user. For the registration, you don’t have to provide any credit card information, you just need a valid email address for that. You can sign up/register for AS2Gateway from here. Go to that link and click on Create Account option to create a new account for you.
From the configuration point of view, I think I don’t have to introduce anything for that. Since there is a user interface and it’s self-explainable, you should be able to identify key components of that. For our example, you just have to create a Station with AS2 ID company-y-as2-id and trading partner for Company X. I’ll explain this in next steps.
Configure AS2Gateway for the Example Use Case
As per our example, Company-Y should configure AS2Gateway to send/ receive messages with Company-X. From the AS2 point of view, we should send messages to AS2 station with AS2 ID, company-y-as2-id to the trading partner with AS2 ID, company-x-as2-id. Go through following steps to configure AS2Gateway.
Assuming that you have already registered with AS2Gateway, you just have to create AS2Station using the graphical UI. You can easily navigate to Stations view using left navigation menu of the AS2Gateway. Click on New Station button at the top of the page. Then you just have to give an AS2 ID for your station. In our example, AS2 ID should be company-y-as2-id. And then click the Save button.
Then you should create a Partner within the AS2Gateway to represent your trading partner — in our case, Company-X is the trading partner for Company-Y. For that, you just have to go to the Partner view using left navigation menu and then click on New Partner button at the top of the page.
In partner creation page, you have to specify the AS2 ID of the partner — company-x-as2-id in our example.
Specify the URI to be used while sending messages to this partner. In our example, this URI should be “http://my-public-ip:10080" — my-public-IP part should be replaced with your current public IP and it makes sure it’s publicly reachable.
Then you have to upload your partner’s certificate for the Encryption Certificate field. This should get from the OpenAS2 side (as explained in the following section you have to export certificate chain of your OpenAS2 side station) since it’s the partner for this example.
Optionally, you can configure a subject to be included while sending messages to this partner. Then click on the Save button to complete the partner creation.
Now it’s all done and you should be able to send and receive AS2 messages between AS2Gateway and OpenAS2. To send messages from the AS2Gateway side, you just have to navigate to the messages view using left navigation menu, and send a new message using the Compose Message option. All the received messages to the AS2Gateway will be there in the Inbox tab of the messages view and you can see all the information including transport headers, MDN related information and message payload using the view message option.
To send a message from OpenAS2 side to AS2Gateway, you have placed an input file to the configured input file folder. As per above configuration, it should be the
data/toAS2GStation. Received MDNs will be saved in data/OpenAS2A-to-AS2GStation/mdn folder. Received messages from AS2Gateway to OpenAS2, should be saved to the data/AS2GStation-to-OpenAS2A/inbox folder.
As you have already felt, configuring AS2Gateway for AS2 communication is much easier since it has a simple user interface and utility functionalities for certificate management and SFTP integration.
I hope you have enjoyed the blog and it’s useful to you. If you have any comments or suggestions, feel free to share in the comments.
注意:如果BizTalk報 "The Signing Certificate has not been configured" error using certificates with EDI/AS2,這可能是你的當前用戶和BizTalk實例運行配置的賬戶不是同一個,因此找不到證書。所以必須要用BizTalk服務的賬戶來導 允許命令 runas /user:BizTalkServiceAccount mmc
// loading identity store FileInputStream is = new FileInputStream("/home/rajind/Downloads/keystore.jks"); KeyStore identityKeystore = KeyStore.getInstance(KeyStore.getDefaultType()); String password = "password"; identityKeystore.load(is, password.toCharArray()); // extracting certificate from identity store X509Certificate signCert = (X509Certificate) identityKeystore.getCertificate("as2gx"); List certList = new ArrayList(); certList.add(signCert); Store certs = new JcaCertStore(certList); // create the generator for creating an smime/signed message SMIMESignedGenerator signer = new SMIMESignedGenerator(); signer.setContentTransferEncoding("base64"); // extracting private key from identity store Key key = identityKeystore.getKey("as2gx", password.toCharArray()); KeyPair keyPair; if (key instanceof PrivateKey) { Certificate cert = identityKeystore.getCertificate("as2gx"); PublicKey publicKey = cert.getPublicKey(); keyPair = new KeyPair(publicKey, (PrivateKey) key); } else { throw new UnrecoverableKeyException("Identity store does not contain keypair for alias " + "as2gx"); } // add a signer to the generator signer.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC") .build("SHA1WITHRSA", keyPair.getPrivate(), signCert)); // add our pool of certs and certs (if any) to go with the signature signer.addCertificates(certs); MimeMultipart signedMimeMultipart = signer.generate(finalMessage, "BC"); finalMessage = new MimeMessage(session); // set the content of the signed message finalMessage.setContent(signedMimeMultipart); finalMessage.saveChanges();
簽署過後,MIME 消息如下如示 譯者註:第一部分為實際內容 "sample text content one" (經base64編碼),第二部分為數字簽名