Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Product and Topic Expert
Product and Topic Expert
SAP Cloud Integration (CPI) provides functionality to automatically sign a message with PKCS#7 / CMS compliant signature.
This blog post explains  the details about the configuration options as well as the required background information.
A simple tutorial helps to understand the theory in real life.
In addition, an OpenSSL tutorial shows the techniques executed in the background.
The following concepts are explained:
Hash/Digest, Digital Signature, PKCS#7, CMS, Electronic Signature, OID, CAdES-BES.

Quick Guide


0. Prerequisites
1. Introduction
2. Signer Configuration
2.1. Block Size
2.2. Include Content
2.3. Encode
2.4. Signer Parameters
2.5. Detached Mode
3. Hands-On Example
4. Optional: OpenSSL

0. Prerequisites

To better understand the PKCS#7 / CMS Encryptor we need to understand the PLKCS#7 and CMS standards.
I’ve tried to explain the standard and everything around it with easy words (because my English is not good enough for complicated words) in a separate blog post, so I recommend to read through it.

To follow this tutorial, access to a Cloud Integration tenant is required, as well as basic knowledge about creating iFlows.

To follow the optional OpenSSL tutorial, the command line tool OpenSSL has to be installed locally.
At this point, I'd like to refer to my previous blog post about the PKCS#7/CMS Encryptor, which is not a prerequisite, but interesting reading.
Also, if questions remain open, please have a look at the Security Glossary.

1. Introduction

We start from the very beginning to explain the concepts of signing.
Experienced readers can skip this section.
Can we skip the blog post?
Experienced readers can skip this blog post.

You want to buy something, e.g. a cat
You take a piece of paper, write a contract which covers the product and the price, go to post office and send it to the dealer.
The dealer calls you and says that your request is not valid.
What has happened?
The dealer doesn’t trust a contract that is not signed.
You try it again, this time you sign the contract with your signature.
You receive a package, but it contains a hungry crocodile, for higher price.
What has happened?
Somebody modified the contract replacing animal and price.
You try it again, this time you sign the contract, put it in an envelope which you close with a seal.
Afterwards, you finally receive your fluffy cat (little fat, though).
What has happened?
The dealer trusts the signature and moreover, the contract couldn’t be altered, as it was secured.
What do we learn?
We need two mechanisms to ensure:
The content is not modified -> “integrity”
The content is original -> “authenticity”.

Now let’s transfer this learning to the digital world.

How do we ensure integrity?
A common example where integrity is required:
Downloading software from a web page.
Usually, in addition to the zip file, a checksum is published in the website.
This allows us to verify that the zip is not modified.
So we’re sure that there’s nothing malicious in it (which could e.g. steal our cat photos)

What is a checksum?
In general, it is the same as: “hash” or “hash value” or “hash code” or “digest” or “fingerprint”.
It is a code, a silly combination of characters and numbers.
Can we have an example?
This is a hash code:
And this is a digest:
It is the same

How does it work?
To produce a hash code, we need to use a hash function, or better a cryptographic hash function (CHF).
What’s the difference?
Generally speaking, CHF is more secure.
Differences are fine-granular and security related.

What is a hash function?
Based on an algorithm, the hash function creates a hash code from any input data (e.g. text, image, etc).
Important properties:
- The input can be of any size, where the digest will always have a fix size.
- It is not possible to guess the original text from the digest (one-way).
- Any small change in the input file will produce different digest (hash collision).
- As such, the digest (hash) proves that the original input is not changed (-> integrity).
BTW, no key or secret or password is required here

Any examples for hash functions?
BLAKE (etc), GOST, MD5 (etc), RIPEMD, SHA-256 (etc)

What does SHA-256 mean?
The hash value has a size of 256 bits.
See below for more info.

A diagram would be helpful

How is a hash function used?
We have an important document that should be signed.
We create a hash value with a (cryptographic) hash function (SHA-256).
We send both to the receiver.
The receiver views the document and wonders if it might have been altered.
He creates his own hash value with same hash algorithm (SHA-256).
He compares his own hash value with our value which we sent to him.
As we know, even the slightest change in the document results in a different digest.

Can we look at a dia…

Nice. Can we try it out?
Yes. See below.

So the Signer in CPI is a hash function?
What is it? A fat cat?
No, we have to go one more preparation step further.
Simply using hash is not secure enough.
A malicious hacker who intercepts the e.g. eMail can alter the document, create his own new hash and forward the eMail. Nobody would notice that the document was changed.
So the weak point is: we don’t have authenticity.
To overcome this weakness:
Use digital signature.

What is a digital signature?
In brief: create a hash value and then encrypt it.
In long?
Similar as before, we create a hash value to ensure integrity.
Now we want to protect the hash and "bind" it to the document.
To avoid hacker attacks, we encrypt the hash with a private key.
(As prerequisite, we need a key pair.)
Then send the document along with  the encrypted hash to the receiver.
(As prerequisite, the receiver needs our public key. The public key is public, so there’s no problem with it.)
The receiver can decrypt the encrypted hash with the public key.
Then he can proceed as explained before:
create his own hash and compare..
Why is this more secure?
It is impossible for a hacker to decrypt the hash, to alter the doc and create new hash.
If the hacker alters the doc, creates a new hash and encrypts it himself, then the receiver won’t be able to decrypt with public key.
This would mean that the doc was hacked.

Oh, that sounds complex….
OKOK, here comes the visualization:

What about the keys?
In asymmetric encryption, we always talk about key pairs.
Private and public key are always generated together, they mathematically belong together.
The public key is public and can be published in the internet.
It is not possible to guess the private key from it
To generate a key pair, we use tools, like openSSL, or CPI, etc.
What about the practical example?
<Sigh>. See below

So the Signer in CPI is a digital signature?
We have to go one last education step further.
The signer in CPI is embedded into the CMS standard (PKCS #7).
Now comes the next question,,,

What is PKCS#7 / CMS??
PKCS #7 and CMS are almost the same, because CMS is the successor, the newer version of PKCS #7

What does it mean?
In brief:
It is not just a normal signature, it is more than that.
We’re signing a message and sending it out to a receiver (or multiple receivers).
To enable the receiver to decrypt/verify it, we need to add additional information/metadata to the message (e.g. algorithm info).
Finally, the content, the signature and the metadata are packaged altogether.
All nicely structured, everything he needs to decrypt and verify.
Please refer to my intro blog post for detailed description.

I still don’t know PKCS#7 / CSM...
CMS = Cryptographic Message Syntax
PKCS #7 =  Public Key Cryptography Standard number 7

What about a practical example?
Again, see below.

Is there anything else?
OMG - don't want to know it...
OMG - what is it?
CMS Advanced Electronic Signature, used with Basic Electronic Signature profile
What is an Electronic Signature?
It is like a manual signature, but created electronically. It attaches something digital to a document.
It is legally accepted, according to regulations.
It is different and less secure than a “digital signature”.
What is an Advanced Electronic Signature?
Electronic Signatures come in 3 variants:
Simple, Advanced and Qualified, with increased security.
An AdES  ensures the the signature is linked to the document and that the signer is identified, which can be achieved with PKI.
This makes it similar to digital signatures, but the method is different.
Advanced Electronic Signatures follow the rules specified by eIDAS (Electronic Identification, Authentication and Trust Services)
What is a CMS AdES?
The CMS standard was designed independently from the eIDAS regulations.
As, such, a message that is signed with a CMS-based tool, cannot be accepted as Advanced Electronic Signature.
However, this problem was solved by adding some additional guidelines (enhancements) to the CMS.
These are collected under CAdES.
The spec can be found here.
As a consequence, a document signed with CMS-SignedData and fulfilling the CAdES, would be legally accepted as evidence.
What is CAdES-BES?
The CAdES format is described by ETSI which stands for European Telecommunications Standards Institute, in a document with name TS 101 733 (with various versions).
There are several profiles for different contexts described there.
One is the BES, Basic Electronic Signature, the simplest one.
What does it have to do with the Signer in CPI?
If you need it, you can use the Signer to sign a document fulfilling the CAdES-BES requirement.
However, you need to make sure that you configure the Signer accordingly:
The content and the certificate must be included, and also the message not base42-encoded.
A diagr...
Forget it !

Great. Can we now learn anything useful?
Let’s come to the actual reason for this blog post: explain the settings in the iFlow editor

2. Signer Configuration

Below screenshot shows the property sheet for PKCS#7 / CMS Signer:

Let’s go through the configuration options and explain one by one.

2.1. Block Size

This setting is not to be confused with the "block size" of encryption algorithms, which is fix (can be 64 bits or 128 bits).
The "block size" which can be specified in this property-sheet-setting, is relevant for the Java library (iaik) which implements the CMS standard and which is responsible for performing the actual security operation.
It can be configured to read the incoming data (from message body) in chunks of different size.
This setting can help to improve performance in case of big message size or if is embedded in a streaming scenario.

2.2. Include Content in Signed Data

First of all:
What is Signed Data`?
This is an expression taken from the CMS-specification.
As mentioned above, the CMS is a guideline how to package a message (simplified).
Now, the package depends on what you want to do:
You may want to encrypt, or to sign, etc (see as well my other blog post about encryptor).
For this, the spec uses different terms, referring to “types”.
So the “type” for signing messages is called “Signed Data”.

We can imagine such a "type" as a "structured data type", which has a fix structure, for storing information and data.
That can be names of algorithms, certificates, signatures, texts, numbers, hashes, the current time.
The structure is different dependent if we want to sign, or to encrypt.

Thus. we can imagine a CMS-compliant message as a tree with many child nodes, carrying different kind (type) of information.
One of these nodes is called “Signed Data” if we choose the Signer in CPI.

What does “Include Content” mean?
The CMS standard describes an agreed standard way for transmitting messages in secure manner.
When it comes to signing, it has foreseen that some end-users may wish to separate the digital signature (+ metadata) from the actual content of the message (which is signed. Can be an image or a text, etc).
Why should I want to separate?
Reason could be e.g. the big size of the message content.
However, enabling the checkbox and send the content together with the signature (+metadata) is the common use case.

If separated, where is it?
If we choose to disable the checkbox, then the big part, the content, is kept in the message body of the iFlow message.
The signature (+metadata) is sent in a property called SapCmsSignedData.

If separated, how to verify?
Tools that implement the CMS standard must be aware of this option (sometimes called “detached mode”).
As such, there must be an option to specify the content while verifying the signature.
OpenSSL for instance has an optional -content parameter for the verification.

2.3. Encode Signed Data with Base46

If we select this option, the full message will be encoded with base64.
This is done after being signed.
If we don’t enable this checkbox, then the message body will be sent over the network as encrypted (binary) data.
This might cause problems, related to special characters that might get lost if transport protocol doesn’t handle properly.
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).
As Cloud Integration will always send messages over wire, enabling this setting would always make sense.
After message processing, the receiver will base64-decode the message, then continue with normal signature verification, i.e. decrypt the hash.

I'm confused: Encoding? Encryption?
Agree, it is confusing because sometimes both terms are even used synonymously.
But in fact, the difference is:
Encryption makes the data un-understandable.
Encoding just transforms the data into different format.
Decryption requires secret password or key.
Decoding is open and can be done by everybody.
Actually, the CMS Encryptor is a good example, because it encrypts the message and in addition, it allows to encode it, to make it readable, although not understandable.

2.4. Signer Parameters

This is a list where potentially multiple entries can be defined.
Each entry is a configuration of one signing process.

Why do we need a list?
Similar like for the Encryptor, we can send one message to multip le receivers.
Each receiver (typically) has a different private key, so we need a list-entry for each receiver.
Furthermore, CMS supports different configuration of the signing, specific to each receiver.
So the designers of the PKCS #7 standard have nicely foreseen this requirement of sending one message to multiple receivers.
All receiver-info is stored as a list in the CMS structure.

2.4.1. Private Key Alias

As we know, the private key is used for signing, not the public key (the public key is used for encryption).
But anyways, in case of signer, we need to specify a certificate which contains both, the private key and the public key.
Because the public key has to be included in the CMS-package, because the receiver will need it to verify the signature.
As the public key is public, there’s no issue with sending it.
However, there must be the certificate (containing the public key) as well, to prove the authenticity.
For a normal, non-CMS-compliant, digital signature, only the private key is required for signing and only the public key for verification (no certificate).
In automated scenarios like CPI, the CMS standard ensures trust via certificate.

2.4.2. Signature Algorithm

Remember what we’re talking about?
We’re looking in detail at the (CMS-based) digital signature feature offered in SAP CPI.
As we’ve learned above, this means:
1. A hash value is generated for the important sensitive message.
2. The private key is used to encrypt the hash value.

So we’re talking about 2 different types of algorithms: used for:
1. hashing 
2. encrypting

The signer configuration allows to choose from a long list of combinations of hashing and encrypting algorithms.

The long list boils down to basically
3 families of cryptographic hash functions
3 encryption types

For instance, the difference between different hash functions of the same family:
the size of the generated hash value.

So let’s briefly introduce them

Stands for Secure Hash Algorithm which is a family of hash functions published by NIST (National Institute of Standards and Technology).
The family consists of:

SHA: original version, 160 bit, since 1993, unsafe.
SHA-1: 160 bit, replaced the original version, but removed at 2010.
SHA-2: since 2001, consists of
SHA-256 with 256 bits 
SHA-512 with 512 bits
In addition: SHA-224 and SHA-384 and SHA-512/224 and SHA-512/256
SHA-3: same properties as SHA-2 but internally the hash is computed differently. Since 2015.

Stands for RACE Integrity Primitives Evaluation Message Digest.
Family of cryptographic hash functions since 1996.
RIPEMD-160 has not been broken.
Size of hash value: 160 bits (20 bytes).
The family consists of:

RIPEMD: output hash value size: 128 bits, weak
RIPEMD-128: output hash value size: 128 bits, weak
RIPEMD-160: output hash value size: 160 bits, most common
RIPEMD-256: output hash value size: 256 bits, similar security level
RIPEMD-320: output hash value size: 320 bits, similar security level

Stands for Message Digest Algorithm No 2 and was designed by Ronald Rivest in 1989, for 8-bit computers.
Size of hash value: 128 bits (16 bytes).
Considered weak

Message Digest Algorithm No 5, since 1991
Designed by Ronald Rivest in 1991 to replace MD4.
Size of hash value: 128 bits (16 bytes).
The hash is represented as 32-digit hexadecimal digits.
considered unsafe

MGF stands for Mask Generation Function.
It is almost the same as cryptographic hash function, with following difference:
CHF generates values of fix size.
MGF generates values of fix size, but it can be configured.
The common concretization is MGF1, which was defined in PKCS #1.

After going through the hash algorithms supported by CPI, let’s quickly check the (asymmetric) encryption algorithms.
The choice of encryption algorithm in your iFlow must match the private key.
Means, only if the private key was generated with e.g. DSA, you have to choose DSA in the “Algorithm” dropdown.

Stands fo Rivest Shamir Adleman (three academics who designed this algorithm in 1977).
One of the most widely adopted asymmetric algorithms, commonly used by PKI cryptosystems.
The RSA algorithm is used to generate key-pair.
RSA supports key sizes 1024, 2048, 4056

This supports a way of message recovery by adding part of the message content into the signature.
The ISO/IEC Standard about “Digital signature schemes giving message recovery” can be viewed here.

Digital Signature Algorithm, published by NIST in 1991
Asymmetric algorithm.
Key size smaller.
Designed and used for digital signature and verification (faster than RSA).
Not secure enough anymore

Elliptic Curve Digital Signature Algorithm.
Variant and successor of DSA, uses ECC (Elliptic Curve Cryptography).
Asymmetric algorithm.
Faster than RSA, uses shorter keys, suitable for small devices.

Any doubts?
What should I use? Short answer please.
Short answer: long digests.
For more security, use bigger hash length and recent algorithm.
As such, SHA3-512 should be a good choice, but SHA-256 (SHA2-family) is strong as well
Also RSA for encryption is always not bad choice.

2.4.3. Include Certificates

As described above, the CMS standard describes a way for putting information into a message in a structured way.
The goal: the receiver of the message should be able to decrypt/verify and read the message, so that it is all safe and all are happy.
In case of verification of a digital signature (based on CMS), the receiver needs the certificate (which includes the public key).
As such, the certificate is added to the CMS package.
In case of multiple receivers with different certificates, all different certificates are stored in the CMS package.
The receiver CMS-tool will find the right one by reading the metadata.

However the CMS specification doesn’t enforce the certificate to be added to the CMS package.
So if a receiver already has the certificate, it is not required to add it to the CMS package.
Note that I’m saying "CMS package" in order to make things easier.
The correct term would be: certificates are added to the “SignedData” element.

The relevant section of the spec can be found here.

The cms command of OpenSSL supports a parameter to specify the certificate, in case it is not included.

So what to do with this setting?
I guess that in most cases it will be set to “true”, which is the default.

2.4.3. Include Signing Time

The signing time is an attribute of the “SignedData” element in the CMS-package.
It is optional, so here in the property sheet we have the choice to include it or leave it.
The time can be checked by the receiver.
It is another security feature, to ensure that the received message signature is not outdated.
The validity of the signature can be ensured by checking the time, just as an example

I see no reason why not include it.

2.5. Detached Mode

Now let’s have a look at the configuration options, when selecting the so-called detached mode.
This is not an official term, at least it is not mentioned in the spec.
The spec talks about “external signature”  which means that the signature is separated from the actual content (as already explained above).
So if we disable the checkbox “Include Content in Signed Data”, then we get another field, where we get more configuration options.

Why is it necessary?
According to the spec, if the content is not included in the CMS package, then it is still required that the metadata contain the info about the type of the content.
That’s all.

2.5.1. OID for Content Type

When we decide to not include the content in the CMS package, then we have to answer 2 questions:

1. Where is the content and where the CMS-package?
2. Which type does the separated content have?

1. The first question was already answered above:
The content is transmitted in the message body of the iFlow, as usual.
The signature along with all other metadata (the CMS-package, how I call it) is put into a special property (SapCmsSignedData)

2. The second question has to be answered within the drop-down field of the property sheet:
We have to choose an OID, to let the CMS-tooling know about the type of the separated content.

What is an OID?
This is the abbreviation of “Object Identifier”.
What Object Identifier?
This is the attempt of giving everything in the world a unique identifier, which allows to describe it and exactly refer to it.
OIDs are structured in a tree hierarchy and the flattened notation is a chain of numbers separated by dots.
Example: 1.2.840.113549.1.7.1
If you encounter such an OID, you can go ahead and copy it into this repository web page:
Then enjoy the description of each tree node and see the rfc that defined the OID, resp child nodes.

In our case:
The CMS standard specifies some structured types, as we've learned above.
One type is called SignedData and has the OID 1.2.840.113549.1.7.2
If a sender sends a message and chooses this type (SignedData) then this means that the sender wants to send e.g. a text and a signature.
"SignedData" means that the message contains the following info:
- the content itself (text)
- the signature (etc)

To be more precise:
- the content and info about the type of the content.
- the hash itself, the hashing algorithm, the encryption algorithm, the public key along with certificate (can be multiple)

And now we’re coming to the point:
The type of the content is specified as OID, like all other types and elements in the structure.
If the content is not present, then this section of the CMS-package (structure) remains empty, but it is there nevertheless.
In any case, the type of the content has to be specified.
In the property sheet of the Signer we have to specify which content type we’re sending.
And the content-type is specified in the form of an OID

The drop-down list contains 2 default entries.
However, it is editable and we can enter any other OID that represents the content that we want to sign.  OID: Data

This is a generic content type, it represents just some kind of data.
This is the most basic type defined within the CMS standard and it is used by the other CMS-types.
We can find it in section 4 of the CMS spec and there we find the OID as well, defined as:

iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1

and written as 1.2.840.113549.1.7.1
As an example, If we enable the checkbox, to include the content, then the default content type will be set under the hood as :
data with OID 1.2.840.113549.1.7.1

With other words:
If we wish to separate the content from the signature, and if our content is normal data, then we choose the default OID: 1.2.840.113549.1.7.1 (Data)  OID: Digested Data

This is a content type that is specified by CMS (section 7) and represents a “normal hash” (not digital signature).
This “normal hash” (or digest) is put into a CMS package, which contains as well the content and metadata.
This CMS-type has the OID 1.2.840.113549.1.7.5
(it is almost the same OID like “data”, only the last number is different)

The result:
The signer will write the 1.2.840.113549.1.7.5 into the CMS-package as value of a field, as specified by CMS.  OID: Custom

We can also manually enter an OID, but it must be a supported OID, it is validated during deploy.
As an example, we can use OID 1.2.840.113549.1.7.6, taken from the CMS spec

The result:
The signer will write the desired OID into the CMS-package as value of a field, as specified by CMS.

Below screenshot shows the CMS structure of a message that has been signed in detached mode and with manually entered OID for content type.


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"

Direct link:

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 signer, we use a simple iFlow that doesn’t require external connections and defines some dummy message content on the fly.

3.2.1. Message includes content and signature

Create empty iFlow.
Delete the Start Event.
Create Timer Event and connect to End Event.
In the property sheet of Timer, make sure that “Run Once” is selected.
Add Content Modifier to simulate some document to be signed.
In the property sheet of Content Modifier, change to Message Body Tab and enter some arbitrary text.
Add PKCS7 Signer step after Content Modifier.
In the property sheet, add the alias ("simplecert") of the key pair created before.
Leave all other default settings.
Add a Datastore Write operation after the signer.
This enables us to view the result of the signer.
In the properties enter a name of your choice, e.g. "cms_signer".

That’s it, we can save and deploy.
After few seconds, we can view the result in our data store at …/shell/monitoring/DataStores
Download the message entry, open the zip and view the message “body” file:

We can see that it contains the message content in plain text, in addition to unreadable encrypted stuff, and some plaintext metadata like certificate name and time.

Optional: extract the “body” to filesystem, if you wish to process it with OpenSSL as shown below.

3.2.2. Content not included

In this second iFlow we try the option of separating the content from the signature.

Create empty iFlow.
Delete the Start Event.
Create Timer Event (“Run Once”) and connect to End Event.
Add Content Modifier with arbitrary text.
Add PKCS7 Signer step.
In the property sheet, add the alias ("simplecert") and deselect “Include Content…”.
Add Parallel Multicast.
Add a Datastore Write operation (name “cms_signer_content”).
This branch is for storing the message body.
For the second branch, create an End Message event and connect the multicast to it.
Add a Content Modifier to the second branch.
In the property sheet, add this text to the Message Body:
This will write the CMS-structure (without content) to the body of this second message.
Add a Datastore Write operation (name “cms_signer_ext_sig”) to the second branch after the content modifier.
This will store the signature (CMS-package) in the datastore.

That’s it, we can save and deploy.
After few seconds, we can view the result in our 2 data stores.
Download the message entry of “content” data store, open the zip and view the message “body” file:
It contains just the plaintext message content.
Download the message entry of “ext_sig” data store, open the zip and view the message “body” file:
It contains binary unreadable stuff

Optional, if you wish to process the result with OpenSSL:
Extract both “bodies” to file system and rename the first one to “msgContent” and the second one to “cmsSig” (accordingly).

4. Optional: OpenSSL Tutorial

Are you curious as well, to see how signing works under the hood?
It is easy to try it and it helps understanding the whole signing thing.
The only prerequisite: we need to download and install OpenSSL.
OpenSSL is the most commonly used tool (and library) for security-related operations, dealing with certificates, converting, etc etc
Basically, it consists of libraries (for “c”) and a command line tool.

- If you have GIT installed, you can just open the git bash which contains openssl.
- Window users can download openssl starting from here.
Afterwards it might be required to add the openssl.exe to the PATH.

Below tutorial for OpenSSL-signing goes through the concepts discussed in the introduction:
- sign by creating a hash and verify by comparing
- sign with digital signature and use verify command
- base64 encoding
- CMS based sign and verify
- Scenario with CPI-signer und OpenSSL-verifier

4.1. Signing by simple hashing with OpenSSL

In this first step, we create a hash of a text file, as a simple signature.
As described in the introduction, we imagine that we send it to a receiver who verifies the signature by manually comparing.
Note that this is not the procedure for digital signature.

1. Create sensitive data file
For example c:\crypt\contract.txt with some text content.

2. Create hash code
Open command shell, jump into the folder with contract.txt and execute the following command:

openssl dgst -sha256 -out myhash contract.txt

The dgst command is used to generate a 256 bit hash with SHA-256 algrithm.
SHA256(contract.txt)= f7a5f85f2b80792a7b4650f009b130dd1b955d855c99ef64d7b98e5f103f3709

3. Send file and hash to receiver
To simulate sending, we just create a separate folder and copy the contract.txt and myhash files into it.

4. Verify
The receiver checks if the contract has not been altered.
To do so:
4 a) Create own hash code from the received contract.
openssl dgst -sha256 -out dealerhash contract.txt
4 b) Finally compare both hashes:
myhash and dealerhash must be equal

5. Negative test
Let’s assume that the contract has been altered by a hacker.
5 a) To modify the contrat.txt we change one single character of the content.
5 b) Then create another hash code
openssl dgst -sha256 -out wronghash contract.txt
5 c) Finally compare both hashes:
myhash and wronghash must NOT be equal

To get a list of supported hash algorithms:
openssl list -digest -commands

4.2. Digital Signature with OpenSSL

Now we're creating a digital signature.
As learned above, we need a key pair, to add to the dgst command.

1. Create key pair
Below command creates one container with private key and public key.
1 a) The command uses default algorithm RSA and we specify the size.

openssl genrsa -out privkey.pem 2048

1 b) We need the public key, so we have to extract it

openssl rsa -in privkey.pem -out pubkey.pem -pubout -outform PEM

2. Create Digital Signature
Same dgst command as above, but including the -sign option which requires the private key.
The command does the hash generation and encryption in one step.

openssl dgst -sha256 -sign privkey.pem -out mysignature contract.txt
Result is glibberishy binary glibberish

3. Send file and hash via email
To simulate sending, we copy the files into a separate folder

4. Verify
The command does the decryption and verification in one step.

openssl dgst -sha256 -verify pubkey.pem -signature mysignature contract.txt
Result is an “OK” message on command line.

4.3. Use Base64 Encoding

To avoid sending glibbery glibber around the net, we encode the binary encrypted hash, such that we send normal characters (although meaningless).

1. Create Digital Signature

openssl dgst -sha256 -sign privkey.pem -out mysignature contract.txt

2. Encode the binary file with base64

openssl enc -base64 -in mysignature -out mysignature_b64

3. Send file and hash via email
To simulate sending, we copy the files into a separate folder.

4. Decode the base64 file

openssl enc -base64 -d -in mysignature_b64 -out mysignature

5. Verify

openssl dgst -sha256 -verify pubkey.pem -signature mysignature contract.txt

4.4. CMS based Signature using OpenSSL

OpenSSL provides support for CMS, means we can use OpenSSL to create or receive CMS-packages.
One very nice feature: print the CMS structure.

1. Create key pair and certificate
Below command creates a key pair and a self-signed certificate in one step.

openssl req -x509 -newkey rsa -sha256 -nodes -keyout privkey.pem -out cert.pem -subj "/CN=mycert"

2. Create Digital Signature
Below command creates a signature (using the private key) and adds the certificate to the CMS-structure.

openssl cms -sign -text -in contract.txt -out signed.txt -signer cert.pem -inkey privkey.pem

3. Send file and hash via email
To simulate sending, we copy the files into a separate folder.

4. Verify
Below command does not require the original contrat.txt file, because the content is included in the CMS structure. The content is written to the output file.
The -text option removes the headers from the output file
The -noverify option is required, because we're using a self-signed certificate.
Note that we don't need to pass the certificate because it is included in the CMS structure.

openssl cms -verify -noverify -text -in signed.txt -out verified.txt
The result is printed to the console.

5. Optional: view CMS structure
Below verification command prints the full cms structure to the output file.
This is not required, but very nice, as it reveals how CMS works

openssl cms -verify -noverify -in signed.txt -out cmsstructure.txt -print -cmsout

4.5. Sign in CPI and verify with OpenSSL

1. Content Included
As a result of the first hands-on tutorial, we’ve downloaded the message from datastore.
This message was signed with default settings, so it includes the content.
To verify this message with OpenSSL, we use below command.
The -inform option is required because CPI writes binary file (not the default SMIME format)

openssl cms -verify -noverify -inform DER -in body -out verified
Result should be successful

2. Detached mode
During second tutorial, we downloaded and renamed 2 message files:
The CMS-signature and the plaintext content.
As the CMS-package does not include the content, we need to add the content (downloaded) to the verification command:

openssl cms -verify -noverify -inform DER -content msgContent -in cmsSig -out verifiedDetached


In this blog post we’ve learned about the concepts related to the PKCS#7 / CMS Signer.
We’ve tried to answer most questions around:
digital signature
CMS SignedData
OID for content type
Hash Algorithms and Encryption Algorithms

All this should have built the foundation for understanding the PKCS#7 / CMS Signer in CPI.
A practical hands-on tutorial in 2 variants guided through 2 variants of configuration.
At the end, we learned to use OpenSSL to manually execute on the concepts we learned before.

We’ve also learned a lot about the CMS standard, which is a guideline for secure transfer of messages.
The guideline describes how to sign or encrypt (etc) a message, and how to package all required info together in a well-defined structure.

SAP Help Portal
Docu for PCKS#7/CMS Signer
Docu for Message-Level Security

Wikipedia: CHF, Cryptographic Hash Function
Wikipedia: Comparison of cryptographic hash functions
Wikipedia: Digital Signature

Understanding PKCS #7 / CMS standard
The CMS spec can be found here or here and even here
Wikipedia: CMS, Cryptographic Message Syntax
The spec for PKCS #7 can be found here.
S/MIME builds on top of CMS
CMS extension for CompressedData type

ISO 9796 document

The spec
The ETSI document

Wikipedia:OID, Object Identifier
Web-tool to search for OIDs

Official list of unofficial binaries download page
Docu home
Docu for cms command

Understanding PKCS #7 / CMS Encryptor
Security Glossary Blog