Sorry, you need to enable JavaScript to visit this website.

Signing requests for PSD2 APIs

Some of Rabobank’s APIs require your application to sign the API requests. This is to ensure that your request was not tampered with during transit.

In this document

In this document, we describe how to correctly sign the request:

  • Use the sandbox environment first
  • The list of Rabobank APIs that require your application to sign the API requests
  • How to correctly sign the request
  • Step 1: Get your signing certificate
  • Step 2: Create the digest
  • Step 3: Create the signing string
  • Step 4: Sign with your private key
  • Step 5: Create the signature header
  • Step 6: Create a header containing the certificate
  • More information on signatures

Use the sandbox environment first

We recommend you develop your application using the sandbox environment first, where you can use our example certificate if you don't have a real eIDAS certificate yet.

⤓ cert.pem ⤓ key.pem

In the examples below, we have used the same example certificate so you can reproduce the resulting values.

The following Rabobank APIs require your application to sign the API requests:

How to correctly sign the request

To correctly sign the request, you must:

  1. Get your signing certificate
  2. Create the digest
  3. Create the signing string
  4. Sign with your private key
  5. Create the signature header
  6. Create the certificate header

Step 1. Get your signing certificate

Use your (PSD2) eIDAS QSEAL certificate issued by the Qualified Trust Service Provider of your choice.

You can use our example certificate in the sandbox environment if you don't have a real certificate yet.

Step 2. Create the digest

The digest is a base64 encoded hash of the body: Base64(SHA512(body))

  1. Take the body of your request, or an empty string if there is no body.
  2. Pass the body through the SHA-512 hashing algorithm (SHA-256 is also allowed).
  3. Make sure the hashed output is binary. In other words, do not convert it to a string.
  4. Base64encode the output.
  5. Add the result to your digest header and make sure that you declare which hashing algorithm you have used (rsa-sha512 or rsa-sha256).

If you are initiating PSD2 bulk payments

For PSD2 Bulk Payment Initiation, there are additional instructions for signing. See: Signing request for PSD2 Bulk API.

Example

An example of the digest header for an empty body using SHA-256 or SHA-512:

digest: sha-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
digest: sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==
 
Keep in mind: due to security regulation, spaces or line breaks between JSON elements will cause incorrect digest error.

Step 3. Create the signing string

The signing string contains several headers, depending on which API you are using, separated by line breaks. The order is not important, as long as you define them in the same order in the signature header.

Example

date: Tue, 18 Sep 2018 09:51:01 GMT
digest: sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==
x-request-id: 95126d8f-ae9d-4ac3-ac9e-c357dcd78811

Signing headers per API

Account Information:

  • date
  • digest
  • x-request-id

Confirmation Availability of Funds:

  • date
  • digest
  • x-request-id

Payment Initiation:

  • date
  • digest
  • x-request-id
  • psu-id (optional / if and only if included as a header of the HTTP request)
  • psu-corporate-id (optional / if and only if included as a header of the HTTP request)
  • tpp-redirect-uri (mandatory for ‘HTTP POST request)
  • tpp-nok-redirect-uri (optional / if and only if included as a header of the HTTP POST request)

Step 4. Sign with your private key

The signature is the signing string signed with the private key: Base64(RSA-SHA512(signing_string))

  1. Create the signing string (see step 3).
  2. Sign it using RSA-SHA512 and the private key of the signing certificate (RSA-SHA256 is also allowed).
  3. Base64 encode the output.

Example

An example of the signature using the above information:

y5o7gKxmfA6AT6IvZ5L89uWxhjcw0BPqDlfK6WX1pB5vKtOctzwustjHI6TjdgQMzQL9LAJX6izs5lVCB6Bjl/l3ntCt4rigJPzfTLbnSlxBhLcabru+KyC7pu00NasyMzl4kv/1jtxrBqzSsUvCz87IBSTLSeoPCJc4E5ME82Bdpss67RWcVe94UzLW8jsCqrncLxiMsD6d2ZQmnH/S7Gu9zk8g9eJovmLIaVLn4C5vW7khS63hSZf8qdTEDlMI/L+QgYVgZVIijKosYEnCB9tH5OYWS9cQ1g1NBrMHQASg/ZV8CxHkXizYg7gQoTGaKvSeD7QC172OqySblE1A9Q==

Step 5. Create the signature header

The signature header consists of the following components:

Component Example Description
keyId $ openssl x509 -in cert.pem -noout -text The serial number of the certificate as defined in 'TPP-Signing-Certificate' header. The format should be Integer not hex. You can use the openssl command line tool to find the serial number.
algorithm rsa-sha512

Specify which algorithm was used when generating the signature:

  • rsa-sha512 or
  • rsa-sha256.
headers "date digest x-request-id"

The list of headers contained in the signature:

  • lowercase
  • separated by a space
  • in the same order as they have in the signing string
signature   The result from step 4.

Example

The resulting signature header for our example:

signature: keyId="1523433508",algorithm="rsa-sha512",headers="date digest x-request-id",signature="y5o7gKxmfA6AT6IvZ5L89uWxhjcw0BPqDlfK6WX1pB5vKtOctzwustjHI6TjdgQMzQL9LAJX6izs5lVCB6Bjl/l3ntCt4rigJPzfTLbnSlxBhLcabru+KyC7pu00NasyMzl4kv/1jtxrBqzSsUvCz87IBSTLSeoPCJc4E5ME82Bdpss67RWcVe94UzLW8jsCqrncLxiMsD6d2ZQmnH/S7Gu9zk8g9eJovmLIaVLn4C5vW7khS63hSZf8qdTEDlMI/L+QgYVgZVIijKosYEnCB9tH5OYWS9cQ1g1NBrMHQASg/ZV8CxHkXizYg7gQoTGaKvSeD7QC172OqySblE1A9Q=="

Step 6. Create a header containing the certificate

In order to verify your signature, we need you to send us the public certificate in a header.
To do so you need to:

  1. Strip the pem certificate from its begin and end tags.
  2. Remove all line breaks.

Example

The result with our example certificate would be:

TPP-Signature-Certificate: MIIDkDCCAnigAwIBAgIEWs3AJDANBgkqhkiG9w0BAQsFADCBiTELMAkGA1UEBhMCTkwxEDAOBgNVBAgMB1V0cmVjaHQxEDAOBgNVBAcMB1V0cmVjaHQxETAPBgNVBAoMCFJhYm9iYW5rMRwwGgYDVQQLDBNPbmxpbmUgVHJhbnNhY3Rpb25zMSUwIwYDVQQDDBxQU0QyIEFQSSBQSSBTZXJ2aWNlcyBTYW5kYm94MB4XDTE4MDQxMTA3NTgyOFoXDTIzMDQxMTA3NTgyOFowgYkxCzAJBgNVBAYTAk5MMRAwDgYDVQQIDAdVdHJlY2h0MRAwDgYDVQQHDAdVdHJlY2h0MREwDwYDVQQKDAhSYWJvYmFuazEcMBoGA1UECwwTT25saW5lIFRyYW5zYWN0aW9uczElMCMGA1UEAwwcUFNEMiBBUEkgUEkgU2VydmljZXMgU2FuZGJveDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANoAjqGWUgCIm2F+0sBSEwLal+T3u+uldLikpxHCB8iL1GD7FrRjcA+MVsxhvHly7vRsHK+tQyMSaeK782RHpY33qxPLc8LmoQLb2EuiQxXj9POYkYBQ74qkrZnvKVlR3WoyQWeDOXnSY2wbNFfkP8ET4ElwyuIIEriwYhab0OIrnnrO8X82/SPZxHwEd3aQjQ6uhiw8paDspJbS5WjEfuwY16KVVUYlhbtAwGjvc6aK0NBm+LH9fMLpAE6gfGZNy0gzMDorVNbkQK1IoAGD8p9ZHdB0F3FwkILEjUiQW6nK+/fKDNJ0TBbpgZUpY8bR460qzxKdeZ1yPDqX2Cjh6fkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAYL4iD6noMJAt63kDED4RB2mII/lssvHhcxuDpOm3Ims9urubFWEpvV5TgIBAxy9PBinOdjhO1kGJJnYi7F1jv1qnZwTV1JhYbvxv3+vk0jaiu7Ew7G3ASlzruXyMhN6t6jk9MpaWGl5Uw1T+gNRUcWQRR44g3ahQRIS/UHkaV+vcpOa8j186/1X0ULHfbcVQk4LMmJeXqNs8sBAUdKU/c6ssvj8jfJ4SfrurcBhY5UBTOdQOXTPY85aU3iFloerx7Oi9EHewxInOrU5XzqqTz2AQPXezexVeAQxP27lzqCmYC7CFiam6QBr06VebkmnPLfs76n8CDc1cwE6gUl0rMA==

More information on signatures

See:
https://tools.ietf.org/html/draft-cavage-http-signatures-10
https://tools.ietf.org/html/rfc3230