Technical Articles
How To .. Configure Inbound AS2 with Dynamic Encryption and Signature Verification using Partner Directory on Cloud Integration
This blog will focus on configuring SAP BTP Cloud Integration AS2 Sender adapter and Partner Directory to dynamically select the security artifacts used for Encryption and Signature Verification by providing step-by-step instructions.
Bonus: Additionally will cover AS2 Outbound Adapter configuration using Encryption and Signature Verification.
Scenario
Our company R-Co is engaging organizations “Alpha” and “Bravo” and has agreed to exchange EDI documents through AS2 protocol, each of them has its respective security artifacts (Keypair, public and private certificates) which are used to secure the communication and protect the data exchanged.
Requirement
Our company has requested to build an integration service to exchange EDI documents that support multiple partners using AS2 protocol over HTTPS, authenticating using TLS mutual authentication, all messages must be encrypted and signed using specific certificates per partner.
Solution
Organization Alpha will be Partner_A
Using:
Signing Algorithm – SHA1
Encryption Algorithm – 3DES
Signed MDN Algorithm – SHA1
X.509 – SXXXXXX813.p12
Organization Bravo will be Partner_B
Using:
Signing Algorithm – SHA512
Encryption Algorithm – AES256
Signed MDN Algorithm – SHA512
X.509 – SXXXXXX184.p12
Our company will be R-Co using SAP BTP Cloud Integration
Service Endpoint: https://r-co.it-cpi003-rt.cfapps.us10.hana.ondemand.com/as2/as2
Message Subject: msgB2BPartners
X.509 – Tenant Keypair: sap_cloudintegrationcertificate
Basic Certificate Usage
Let’s understand how a basic setup works.
B2B Sender Partner | ||
Function | Signature | Self Private Key |
Function | Encryption | B2B Receiver’s Public Key |
Function | MDN Verify Signature | B2B Receiver’s Public Key |
B2B Receiver Partner | ||
Function | Verify Signature | B2B Sender’s Public Key |
Function | Decryption | Self Private Key |
Function | MDN Signature | Self Private Key |
Now mapping to our scenario
Partner A | |||
KeyStore | Key Pair | Self Private Key | SXXXXXX813.p12 |
Self Public Key | |||
Self Public Certificate | SXXXXXX813.cer | ||
B2B Sender’s Public Key Certificate | sap_cloudintegrationcertificate.cer | ||
Cloud Integration Load Balancer Root Certificate |
DigiCert Global Root G2.cer |
Partner B | |||
KeyStore | Key Pair | Self Private Key | SXXXXXX184.p12 |
Self Public Key | |||
Self Public Certificate | SXXXXXX184.cer | ||
B2B Sender’s Public Key Certificate | sap_cloudintegrationcertificate.cer | ||
Cloud Integration Load Balancer Root Certificate |
DigiCert Global Root G2.cer |
Cloud Integration | |||
KeyStore | Key Pair | Self Private Key | sap_cloudintegrationcertificate.p12 |
Self Public Key | |||
Self Public Certificate | sap_cloudintegrationcertificate.cer | ||
B2B Receiver’s Public Key Certificate | SXXXXXX813.cer alias -> partner_a_813 SXXXXXX184.cer alias -> partner_b_184 |
||
Cloud Integration Load Balancer Root Certificate |
DigiCert Global Root G2.cer |
Build
Now that we have defined how we should communicate with our partners let’s create our service.
Step 1: Create iFlow with Inbound AS2 Sender Adapter and Oubound JMS Receiver Adapter.

You may download the iFlow following link >> download
Step 2: Configure Inbound AS2 Sender Adapter.
Note: Link to the documentation here.
Processing Tab:
Message-ID Left & Right: We will configure a *wildcard* as we are not expecting any specific details from partners.
Partner AS2 ID: We will configure a *wildcard* to be able to receive multiple partners in the same iFlow.
Own AS2 ID: R-Co // We will set our company’s unique identifier.
Message Subject: msgB2BPartners // Message header of the incoming AS2 message.
The rest of the parameters we can leave as default values, if needed please refer to the documentation for all capabilities of the adapter, for now, we would be using the default role, and concurrent or parallel processes is recommended to be set at the minimum (1) per worker node.
Security Tab:
Decrypt Message: Checked // Message will be encrypted and sender side, decrypt is mandatory.
Private Key Alias: pd:ReceiverPrivateKey // Private key alias will be assigned at authentication via partner directory. The Keypair must be imported into the tenant’s keystore.
Verify Signature: Trusted Certificate // Signature will be validated against a certificate in the tenant’s keystore.
Public Key Alias: pd:SenderPublicKey // Public key alias will be assigned at authentication via partner directory. The certificate must be imported into the tenant’s keystore.
Note: However the settings of these parameters if Partner Directory entities are set, partner directory takes precedence and overwrites any configuration on the adapter, please find further details on official documentation.
MDN Tab:
Private Key Alias for Signature: sap_cloudintegrationcertificate // This could be any Keypair in the tenant’s keystore, recommended to use own tenant keypair.
Note: At the time of the writing of this blog this parameter could not be set dynamically.
The rest of the parameters will keep them with default values.
Certificates
Prerequisite: Exchange certificates with your partners.
A) sap_cloudintegrationcertificate. Navigate ➡️ Monitor >> Manage Security >> Keystore >> select certificate >> Actions >> Download Certificate
B) DigiCert Global Root G2 (Load Balancer root + chain). Navigate ➡️ Monitor >> Manage Security >> Connectivity Tests >> TLS. Type iFlow base URL and click Send. Click the Download button.
Note: Private certificates should never be exchanged, only share public certificates (.cer / .der) and complete chain (.pb7)
Step I: Create Service Instance and Service Key type X.509 for client certificate authentication
Note: Please find step by step guide <<wiki>>
Note: For purpose of this exercise we will use an S-User keypair to simulate each partner from where I have extracted the certificate; more details can be found in the following link.
View Service Key
Copy and save “clientid” value:
Step II: Import public certificate from partner and assign aliases (Optional: Only if you would like to test without Partner Directory)
Note: For purpose of this exercise we will use an S-User keypair to simulate each partner from where I have extracted the certificate; more details can be found in the following link.
Navigate ➡️ Monitor >> Manage Security >> Keystore >> Click on Add >> Certificate
Partner_A
Partner_B
Assign an Alias: partner_b_184
Result
Step 3: Configure Outbound JMS Adapter
In our scenario, we will like to send the message to a JMS queue, in a production scenario you might want to pick from that queue or route to a specific iFlow using Process Direct instead.
Queue Name: B2B_Partners
Transfer Exchange Properties: Checked
We are ready to deploy our iFlow
Step 4: Configure Partner Directory
Now we are ready to configure the partner directory but first, we need some fundamentals from the official documentation.
The Partner Directory allows you to store information about communication partners and to parameterize integration flows using this information. The Partner Directory helps you to set up a communication network between many communication partners efficiently. You use the Partner Directory to store partner-specific information. Those components that are parameterized read this information during runtime from the Partner Directory.
The Partner Directory contains the following entities(which can be accessed using an OData API)
The following are specific iFlow components available in Partner Directory:
AS2 sender adapter: sender partner X.509 certificate to verify partner signature, sender partner-specific user, or client certificate
The AS2 sender reads the following parameters from the Partner Directory:
Let’s digest the previous information: Partner Directory is used to store partner-specific information and access this information from the runtime. Partner Directory has predefined entities which can be leveraged to determine specific values for your partners, such as unique ID per partner, authorized users linked to the partner id, and a directory of parameters linked to the partner id. Additionally, the AS2 Sender Adapter has built-in Partner Directory capabilities.
We can now start the configuration of the Partner Directory.
Note: Please refer to the official documentation or personally recommended blog on how to execute crud operation using Postman.
- Create Partner ID in Partner Directory.
We can create Pid or Partner ID by creating a String Parameter.{ "Pid": "MATARTEST_ZZ", "Id": "R-Co_08_850_4010", "Value": "abcdefghijklmnopqrstuvwxyz000001" }
Note: In my case, I have used a specific naming convention for my partner id which includes values from an X12 header document as part of my own strategy, this is optional, Partner ID can be any value that is unique for your directory. Example: Pid can be an ERP ID “100000099”, Id can be the endpoint address “URL-Address”, and Value can be the actual endpoint “https://acme-as2.com/inbound”
- Create an Authorized User in Partner Directory
We linked the Pid to a user by creating an Authorized Users entity.
URL: {{UI_tenant_url}}/api/v1/AuthorizedUsers
Method: Post
Body in JSON:{ "Pid": "MATARTEST_ZZ", "User": "sb-cb4b8731-0dc9-44a4-bd21-16cdfaf35aaf!b17506| !b2455" }
Pid value is the unique value representing your partner.
User value should be retrieved from the service key linked to the partner certificate, this is the same value we retrieve from SAP BTP Cockpit. - Create Partner Directory Parameters for AS2 Sender Adapter
- Decrypt Message. This parameter is needed if partners are encrypting the message. We create a String Parameter for our Pid and assign Id: “AS2_inbound_decrypt_message” and the value: “true”
URL: {{UI_tenant_url}}/api/v1/StringParameters
Method: Post
Body in Json:
{ "Pid": "MATARTEST_ZZ", "Id": "AS2_inbound_decrypt_message", "Value": "true" }
- Private Key Alias. This is the alias for the keypair which is used for decrypting the message. Recommended to use tenant’s keypair but any keypair already imported can be used. We create a String Parameter for our Pid and assign id: “ReceiverPrivateKey” and the value: “sap_cloudIntegrationcertificate”
URL: {{UI_tenant_url}}/api/v1/StringParameters
Method: Post
Body in Json:{ "Pid": "MATARTEST_ZZ", "Id": "ReceiverPrivateKey", "Value": "sap_cloudintegrationcertificate" }
- Verify Signature. This parameter is to set request the adapter to verify the signature. We create a String Parameter for our Pid and assign id: “AS2_inbound_verify_signature” and assign the value: “trustedCertificate”
URL: {{UI_tenant_url}}/api/v1/StringParameters
Method: Post
Body in Json:{ "Pid": "MATARTEST_ZZ", "Id": "AS2_inbound_verify_signature", "Value": "trustedCertificate" }
- Public Key. This parameter contains the public certificate in PEM format, without header and footer, no spaces, or newlines. We create a Binary Parameter for our Pid and assign content-type: “crt” and value: “{{certificate_PEM}}”
URL: {{UI_tenant_url}}/api/v1/BinaryParameters
Method: Post
Body in Json:{ "Pid": "MATARTEST_ZZ", "Id": "SenderPublicKey", "ContentType": "crt", "Value": "MIIDkDCCAnigAwIBAgIOAO...VNxcW4SwvUHIbSg==" }
- Decrypt Message. This parameter is needed if partners are encrypting the message. We create a String Parameter for our Pid and assign Id: “AS2_inbound_decrypt_message” and the value: “true”
We have completed the configuration for Partner_A, please repeat all tasks for Partner_B. When finalized if all API calls have been executed successfully you will be able to have the following parameters configured in your tenant.
Note: I have used Pid: “MATARTEST_ZZ” ➡️ Partner_A and Pid: “MATARSYST_ZZ” ➡️ Partner_B
Binary Parameter:
Testing
To be able to test we need an AS2 tool to send documents to our iFlow, a good option is Mendelson also referenced by the official documentation unfortunately at the moment of writing this article Mendelson support has confirmed that Client Certificate Authentication is not working in the community version (forum) so instead we will use SAP BTP Trial – Cloud Integration.
Note: Please find a blog on how to enable a trial account <<blog>>
Step 1: Certificate Management
Cloud Integration Trial tenant will be acting as B2B Sender System for Partner_A and Partner_B so we need to maintain the proper security artifacts.
- Import Keypair in Cloud Integration Keystore.
Navigate ➡️ Monitor >> Manage Security >> Keystore >> Click on Add >> Key Pair
Partner_A >> alias >> partner_a_813
Partner_B >> alias >> partner_b_184
Cloud Integration r-co tenant will be acting as B2B Receiver System so we need to maintain the public key from the sap_cloudintegrationcertificate Key Pair.
- Navigate ➡️ Monitor >> Manage Security >> Keystore >> Click on Add >> Certificate
assign alias >> cpi_w
If imported successfully must have the following entries on the trial’s tenant keystore
Keypair:
Certificate:
Step 2: Create iFlow
- Create an iFlow with two Integration processes, two HTTPS Sender Adapter, two AS2 Receiver Adapter.
- Configure HTTPS Sender Adapter
2.1 Create first endpoint as: /partner_a2.2 Create second endpoint as: /partner_b
For simplicity will disable CSRF protected, and leave all default values.
Step 3: Configure Outbound AS2 (Receiver) Adapter
Note: Please refer to the Certificate section above for clarification on certificate usage.
Note: For purpose of this exercise we will use an S-User keypair to simulate each partner from where I have extracted the certificate; more details can be found in the following link.
- Configure AS2 Receiver Adapter – Partner_A
- Connection – Client Certificate Authentication – Select Authentication Type as Client Certificate and type in the alias created >> partner_a_813
- Processing – Own AS2 ID: “Partner_A“, Partner AS2 ID: R-Co, Message Subject: “msgB2BPartners“, and Content-Type Application/EDI-X12
- Security – As defined Sign Message: Checked, Algorithm: SHA1, Private Key Alias: partner_a_813, Encrypt Message: Checked, Algorithm: 3DES, and Public Key Alias: cpi_w (sap_cloudintegrationcertificate)
- MDN – Type: Sync, Request Signing: Checked, Algorithm: SHA1, Verify Signature: Checked, and Public Key Alias: cpi_w (sap_cloudintegrationcertificate)
- Connection – Client Certificate Authentication – Select Authentication Type as Client Certificate and type in the alias created >> partner_a_813
- Configure AS2 Receiver Adapter – Partner_B
- Connection – Client Certificate Authentication – Select Authentication Type as Client Certificate and type in the alias created >> partner_b_184
- Processing – Own AS2 ID: “Partner_B“, Partner AS2 ID: R-Co, Message Subject: “msgB2BPartners“, and Content-Type Application/EDI-X12
- Security – As defined Sign Message: Checked, Algorithm: SHA512, Private Key Alias: partner_b_184, Encrypt Message: Checked, Algorithm: AES256, and Public Key Alias: cpi_w (sap_cloudintegrationcertificate)
- MDN – Type: Sync, Request Signing: Checked, Algorithm: SHA512, Verify Signature: Checked, and Public Key Alias: cpi_w (sap_cloudintegrationcertificate)
- Connection – Client Certificate Authentication – Select Authentication Type as Client Certificate and type in the alias created >> partner_b_184
- Save and Deploy
After successfully deploying we should have two endpoints, which will simulate sending data as Partner_A and Partner_B in compliance with the initial requirement and technical details.
Step 4: Complete E2E testing
We can test our scenario using a local client, I will use Postman to call the HTTPS endpoint and send a dummy EDI file. Note: Please find a video tutorial on how to create credentials and execute iFlow <<video>>
- Partner_A Test – X12 850
Note: If successful reply will contain MDN details - Partner_B Test – X12 855
Results
After execution, we can check the logs on both tenants.
Monitoring – Outbound (Trial tenant)
Outbound Message – Partner_B
MDN Attachment – Partner_B
Same values as per Postman responses.
Monitoring – Inbound
Navigate ➡️ Monitor >> Message Processing >> All Integrations Flows
Select Message for iFlow: IF_AS2_Inbound_to_JMS
Inbound Message – Partner_A
The Partner ID was retrieved automatically using Partner Directory Binary Parameter and AuthorizedUser entity.
Trace – Partner_A
Will deep dive into the header values to validate the user, certificate, and AS2 envelop values.
Header Values – Partner_A
Note: We can compare x-forwarded-client-cert and SAPAuthenticatedUserName values against the service key in SAP BTP Cockpit.
At last, we analyze if the data was decrypted.
Payload – Partner_A
Analyze decrypted payload
Inbound Message – Partner_B
The Partner ID was retrieved automatically using Partner Directory Binary Parameter and AuthorizedUser entity.
Will deep dive into the header values to validate the user, certificate, and AS2 envelop values.
Header Values – Partner_B
Note: We can compare x-forwarded-client-cert and SAPAuthenticatedUserName values against the service key in SAP BTP Cockpit.
At last, we analyze if the data was decrypted.
Payload – Partner_B
Analyze decrypted payload
Monitor Queue
Messages are available for further processing we can corroborate the Message-ID corresponds to the ones shown in the Message Monitor screen.
Conclusion
We have demonstrated that SAP Cloud Integration with the Partner Directory can dynamically select the correct certificates, and configuration to process the incoming data from different business partners. Thanks
My goal was to provide you with a guide on how to configure AS2 Adapters in SAP BTP Cloud Integration while leveraging Partner Directory built-in capabilities using client certificate authentication, hopefully, this can help you in your projects, keep integrating 🖖🏻
Regards
Hello , Thank you for the wonderful blog . A quick question , We have a integration suite standard edition and we would like to use AS2 , do we still need to subscribe to Event mesh/Enterprise messaging? It will be great if you can reply ? Did you use Enterprise Edition or standard edition of integration suite?
Hi Deepa,
If you have a new pricing model for Standard Edition the JMS queue functionality is already included without any cap.
For the blog, I was using Premium Edition and Trial.
Best regards
Hi Ricardo,
new pricing model meaning message based licensing?
Cheers
Jens
Hi Jens,
AS2 protocol leverages internal JMS queues. JMS can be enabled when provisioning the Cloud Integration capability within the Integration Suite.
FYI in NEO or older licensing models, you were required to activate Enterprise Messaging to enable the JMS queues.
I hope this helps.
Regards,
Thanks Ricardo,
so my takeaway would be (when using Integration Suite's Cloud Integration Standard Edition on Cloud Foundry - man, SAP's naming really sucks / rules - pick your choice 😉 )
Many thanks and kind regards
Jens
Thank you and another question.. i just followed your blog .. i was able to test from postman but when the sender sends me a test ..it gives us a bad request- Question my sender wantst to use a client certificate for authentication ..i created a service key iwth the the clinet certificate.. do i have to provide him anything?
Hi Paramasivam,
I don't fully understand your question.
Sender systems need to have a valid certificate (valid = root certificate signed by a CA approved by SAP) and import the load balancer certificates.
Please refer to the Basic Certificate Usage section. If you need to troubleshoot, please check my blog: https://blogs.sap.com/2021/07/22/how-to-troubleshoot-client-certificate-authentication-for-inbound-communication-to-cloud-integration-using-wireshark/
Regards,
Hi Ricardo Israel Mata Viejo,
We have tried to implement the receiver As2 adapter for reading the public certificate like "Public Key Alias: Pd: Certificate" stored the certificate in PD, but we are getting null exception.
Below error is coming:
Remote server returned response code -1 and error message Error while opening connection to the server: java.lang.NullPointerException: while trying to invoke the method iaik.x509.X509Certificate.getPublicKey() of a null object loaded from the first parameter of the method, cause: java.lang.NullPointerException: while trying to invoke the method iaik.x509.X509Certificate.getPublicKey() of a null object loaded from the first parameter of the method
Could you suggest something if any additional steps to follow.
Regards,
Hi Ricardo,
I notice the service keys you created for partner_A and partner_B external certificates have different clientid assigned to it in BTP. Did you create these service keys under the same Service Instance (ie., x509_client_certificate_auth in your example)? Because if I create Service keys for all partners under the same Service Instance, all the Partners are assigned same clientId.
With the same clientID assigned for all partner certificates, How would I differentiate the AuthorizedUsers and retrieve the encoded certificate from partner directory BinaryParameters?
Please suggest.
Regards,
Kavita
This is an impressive blog, Ricardo! I'm glad there is the Trading Partner Management available now, which makes a lot of the above much easier and efficient (mainly the dealing with the Partner Directory).
Philippe
And by the way: I was wondering why you create Client Certificates for the inbound authentication. You could as well simply use Basic Authentication (and therefore easily test with Mendelson AS2) using the Service Key credentials (client ID and secret).