SAP Cloud Integration: Understanding “Simple Signer” 
SAP Cloud Integration (CPI) provides functionality to automatically sign a message with a digital signature.
This blog post explains the basics about digital signatures and shows the usage in a simple tutorial..
2. Signer Configuration
3. Hands-On Example
To follow this tutorial, access to a Cloud Integration tenant is required, as well as basic knowledge about creating iFlows.
For remaining open questions I recommend the Security Glossary.
The “Simple Signer” is not as simple as one might expect.
The “Simple Signer” creates a “digital signature”.
But that’s not simple.
Let’s have a closer look at it and answer questions like:
What is the difference between a really simple signing and a digital signature?
What is a signature at all?
What else can be mentioned to confuse innocent people?
At this point, I’d like to point you to my PKCS#7/CMS Signer Blog post where I’ve explained some basics of signing, in details and with diagrams.
Let’s summarize the explanations of that blog post (which is still recommended reading).
What is signing?
It all starts with some important content (can be a text, of a file, or any binaries).
The content is not really secret, but we want to make sure that it is not changed (by any hacker) after we’ve sent it over the internet.
For that purpose, we create a hash code, based on the content.
Means, afterwards we have 2 files (content and hash), for instance.
To create a hash code, we use an algorithm (e.g. with a tool like OpenSSL).
We pass the important textfile as input and the output is the hash code.
A hash code is just some chain of meaningless characters (see below for an example).
The point is:
The hash code is always the same, for the same input.
(using the same algorithm)
If a hacker changes the original text, then the hash will be different.
How does that help?
As such, we can send the original content and the hash code to the receiver.
The receiver will create another hash code based on the received content.
Then compare the new hash with the received hash (verify).
They must be equal. Otherwise it is proven that the content has been altered.
This is called integrity:
Ensuring that the content has not been altered.
BTW, hash code or hash value is just another name for digest (sounds cooler) or fingerprint (frequently used, e.g. in certificates)
However, this mechanism is not finally safe, because a hacker might modify the content, then create a new digest and send it.
Actually we don’t know “who” created the digest.
What we’re missing is: authenticity.
To achieve it, we proceed as follows:
-> We have the original content.
-> We create the digest.
-> We encrypt the digest.
For the last step, we use asymmetric encryption, which means we use a key pair.
A key pair has the important characteristic that both keys belong together.
We use the “private key” for the encryption.
The specialty of the private key is: it is “my” key, only I have it. I never share it with anybody.
I keep it secret like a password.
We send everything to the receiver:
the actual content
the encrypted digest
the public key
The receiver decrypts the digest with the public key.
If this works fine, then the receiver is sure that the digest was encrypted with “my” private key.
This ensures the required “authenticity”.
Afterwards, the receiver can verify the digest, to ensure the “integrity”.
So this is what we call a digital signature.
In detail, things are a bit more complicated.
We don’t do these steps manually, we use a command to create a digital signature, and in fact there’s a little difference between “hashing/encrypting” and “creating digital signature”.
The difference is in the padding scheme, as described in the spec.
So the difference between a “normal” signature and a “digital signature” is the “authenticity”, which is achieved via encryption with key pair.
Now, there’s a third security aspect which is typically mentioned in the context of digital signatures: non-repudiation.
What does non-repudiation mean?
Let’s think about an example:
I want to buy a fluffy cat… 🐈
I order it and I send a contract with digital signature.
After receiving it, I realize that the cat meows all the time and plays with mice and sleeps anywhere and for me it shows only the back… 😼
So I claim that I didn’t order it.
The vendor won’t accept my complaint, he’ll insist in:
1. The cat behaves like just all cats do. 😹
2. The signature was created with “my” private key, proven by the public key.
As such, it must have been me who signed and who ordered.
Hence, I may not repudiate.
However, there’s a weak point about it:
The key-pair only proves that the signature was created by “someone” having the matching private key.
Not necessarily “me”.
To overcome this insufficiency, a certificate comes into play.
A certificate is issued and signed by a publicly accepted Certification Authority.
As such, it can prove that the public key really belongs to “me”.
But there’s a “however”:
Coming to CPI…
The “Simple Signer” in CPI doesn’t support sending certificate (nor public key) along with the message.
As such, we as users need to manually make sure that the receiver gets what he needs.
So if full “non-repudiation” is required, the “PKCS #7 / CMS Signer” in CPI should be used.
But, there’s another “however” on the above “however”:
I don’t see a way to upload a key pair without certificate to CPI Keystore dashboard.
Hence, when using CPI, we always have a certificate at hand, so we can send it to the receiver.
The certificate includes the public key, which is required for verification
Is it legally binding?
Let’s come back to my example:
My cat is still scratching my furniture, my hands, is playing with mice in my apartment, meowing when I want to enjoy dinner and jumping on my belly when I want to sleep.
I submit this case to a court.
The judge, after recovering from laughing, would probably have to accept my complaint:
Because the “normal” digital signature is not legally binding.
For legally binding virtual signatures, there have been regulations established, accepted by national legal institutions, etc.
One example is the “Advanced Electronic Signature” powered by CMS, which is supported by the “PKCS #7 / CMS Signer” in CPI (CAdES, see my blog).
So an Electronic Signature…?
Yes, an “Electronic Signature” is again something different, but it may build on technology used by digital signatures.
Why use “Simple Signer”?
I guess, in many scenarios covered by CPI, a “normal” digital signature would be sufficient, because an admin would administrate all systems connected via CPI.
Hence the involved systems would trust the key pair.
Another reason why using the “Simple Signer” instead of the “PKCS #7 / CMS Signer”:
A “normal” digital signature can be verified by many tools and libraries.
However, there are only a few tools and libs that are able to process a CMS-based message.
Another possible consideration could be the performance impact: A CMS-based message carries not only the digital signature, but also all required artifacts.
How does the “Simple Signer” Work?
It creates a digital signature, for the content in the message body.
A signature has binary DER format, which is not suitable for sending it over the net.
As such, the “Simple Signer” automatically converts the signature to Base64 encoding.
The resulting string is then stored in a message header.
The name of the header can be configured in the property sheet of the signer.
What is Base64?
Encoding just transforms the data into different format.
When encoding with Base64, we’re on the safe side, because the character set that is used to transfer the message contains only normal characters (alphabet upper and lower case, numbers and 3 others => 64).
After message processing, the receiver will base64-decode the message.
No secret key nor anything is needed for it.
The difference is:
Encryption makes the data un-understandable.
Decryption requires secret password or key.
How to verify?
Currently, there’s no “Simple Verifier” in the CPI editor, so if verification is required in an iFlow, it has to be manually implemented (see next blog post).
2. Signer Configuration
In this chapter we’re going to have a closer look at the meaning of the configuration options for the “Simple Signer” and see if any explanation is required.
Below screenshot shows the property sheet:
2.1. Private Key Alias
As explained above, when creating a digital signature, the digest is encrypted using a private key.
The “Simple Signer” uses a private key that has to be uploaded beforehand in the CPI Keystore.
The screenshot above shows an example where I generated a private key with certificate, then packaged both into a pfx-keystore.
The “Alias” name is specified during upload in CPI dashboard.
CPI allows to upload self-signed certificates (e.g. generated locally with OpenSSL), so we can easily test. During upload of a self-signed certificate, a warning popup is displayed.
2.2. Signature Algorithm
As explained above, an algorithm is used to calculate the hash value.
With other words, a tool or a library is used to compute the hash, using the desired algorithm.
There are multiple possible algorithms to choose from.
The hash code is always a rather small chain of characters, with a fix size, which doesn’t depend on the size of the original content.
However, the size of the hash code can change when using different algorithm.
using SHA-1 results in a small hash code
using SHA-256 results in a bigger hash code
using SHA-512 results in a even bigger hash code
This was about calculating the digest (hashing algorithm).
Afterwards, the signer will encrypt the digest using an algorithm for asymmetric encryption.
A common algorithm is RSA.
The algorithm which we choose in the property sheet must match the algorithm used when generating the key pair.
Reason is that the private key is used for encryption.
Usually, RSA is used for generating key pairs.
E.g. if no parameter is specified, then RSA would probably be the default.
The dropdown in the signer properties offers a large list of algorithms.
More precise: combinations of hashing and encrypting algorithms.
Above screenshot shows the default which would use SHA-512 for hashing and RSA for encrypting.
In my previous blog post I’ve detailed out the meaning of all these options, while grouping them for better overview.
The default option (SHA512/RSA) is a good option, as it uses strong algorithms.
For strong encryption, make sure to generate a private key with large key size.
2.3. Signature Header Name
As explained in the intro, the “Simple Signer” creates a digital signature and encodes it with Base64.
To transfer the signature along with the message, it is stored in a message header.
The name of the header can be specified in this field.
This is a nice behavior which makes the chosen name explicit.
If you plan to send the message to a HTTPS receiver, make sure to use lowercase names, otherwise your receiver will have a surprise.
3. Hands-On Example
Let’s go through a very simple integration flow, to try it out.
No prerequisites, no tools no adapters required.
3.1. Create Key Pair
We let CPI generate a key pair for us.
This is done in the Keystore of Cloud Integration.
Go to your CPI -> “Operations & Monitoring” -> “Manage Security” -> “Keystore”
Choose “Create” -> “Key Pair”
Enter some values of your choice, e.g. “simplecert” and press “Create”.
The alias is required later, we can take a note of it, or try to remember (or follow my description).
3.2. Create iFlow
To test the “Simple Signer” with minimum effort, we design a simple iFlow that doesn’t require external connections and defines some dummy message content on the fly.
We create an iFlow with the following elements:
- Start Timer set to “Run Once”.
- Content Modifier with arbitrary text in Message Body.
- Simple Signer with “Private Key Alias” and default settings.
- Datastore Write operation with arbitrary name and included headers.
Note: make sure that “Include Message Headers” is enabled in the propert
After deploy and successful execution of the iFlow, we go to our Data Store and have a look at the body file of the zip.
It contains the plaintext content that we entered in the Content Modifier step.
Now we can go ahead and adjust the settings according to the screenshots of section 2.
Not surprising and not interesting.
We close the body, disappointed….
There’s another file in the zip, the headers.prop.
We open it and see something like below:
We can see that the file contains the header that is defined in the Simple Signer properties (default name).
The value of the header is the base64-encoded, digital signature.
I’ve marked the 2 escape characters at the end of the string.
Backslashes are not part of the Base64 characters, they are used to escape the “=” while transferring from CPI to my local machine.
So if you plan to process this file locally with OpenSSL you might need to manually remove those 2 backslashes.
OK, I’ve removed the backslashes and everything else from the file, renamed it to sigb64, and decoded the Base64 file with OpenSSL like this:
openssl enc -base64 -d -in sigb64 -out mysignature
The binary result looks as follows:
Nice and nonsense.
I just like to look at it, because I can get a better impression of what is a “digital signature”.
While we can be happy to experience the base64-encoded digital signature in the message header, we might start wondering if there’s anything else we can do?
Correct: a signature does not make sense if not verified.
As there’s no “Simple Verifier” in the palette of the CPI editor, we need to do the verification manually.
The next blog post shows how to implement the verification in a Groovy script.
This other next blog post shows how to implement the verification in a receiver Node.js application.
And here are a few security considerations, including a hacker scenario: know the weakness
The Simple Signer creates a “normal” digital signature for the message content (message body).
The message content remains untouched, in the message body.
The signature is stored in a header.
The header name can be configured in the property sheet.
As usual for digital signatures, the Simple Signer creates a digest (hash value) and applies asymmetric encryption.
As such, a private key has to be provided in the property sheet.
The private key needs to be uploaded or created in the CPI Keystore.
The (binary) signature is encoded with Base64.
To verify the signature, any standard tool or library can be used
SAP Help Portal
Docu for Simple Signer
Docu for Message-Level Security
PKCS#1 RSA spec
How to verify a digital signature with Groovy script.
How to verify a digital signature in Node.js app.
How to hack the Node.js scenario
Understanding PKCS #7 / CMS Standard
Understanding PKCS #7 / CMS Signer
Very well explained!
Thanks so much Sandesh Kurumella , I'm glad to know that it is understandable!