Validate Signing Requests

To validate your request, Rabobank applies the following security checks to ensure authenticity and integrity:

  • Mutual TLS (mTLS) - The request must be authenticated using an EV SSL certificate.
  • HTTP Request Signing - The request is cryptographically signed following the IETF HTTP Signatures draft standard. The request must be signed using a different EV SSL certificate.
  • Digest header - A hash of the request body is included, as defined in RFC 3230 to guarantee body integrity..
  • OAuth 2.0 - Used to authorize access to the API.
  • Rate limits - Applied to ensure fair usage and maintain system stability.

EV SSL Certificates

Rabobank accepts certificates from the certificates issuers in the Mozilla Certificate Report .

  • TLS Client Certificate: EV SSL certificate from an accepted CA (RSA ≥ 2048 bits, max validity 1 year).
  • Signing Certificate: EV SSL certificate for signing requests.

TLS Certificate

Public

Upload the public part of the TLS certificate (full chain in PEM format) in the Rabobank developer portal under My Organizations → Apps → Configuration → Certificate.

Private

Keep the private key secure in your infrastructure, it is used to set up the mTLS connection.

Signing certificate

Public

The public key should be shared with Rabobank in the Signature-Certificate header of a request.

Private

Keep the private key secure in your infrastructure, it is used for creating the HTTP Signature. Rabobank does not store your signing certificate.

Sandbox vs Production

Rabobank offers two environments: Sandbox for testing and Production for live transactions. These environments have different certificate requirements, domains, and signature. Understanding these distinctions help you plan your move from development to production.

👍

Rate limits can differ for every API and per environment, check our API guides for rate limits per API.

Environment

Certificate

Domain

Signature

Sandbox

Any certificate works for mTLS and Signing;

Rabobank provides downloadable test sandbox certificates and keys for convenience and testing.

TLS

Download Example Certificate **

Download Example Private Key **

Signing

Download Example Signing Certificate

Download Signing Certificate Key


Rabobank servers use EV SSL certificates (e.g., api.rabobank.nl).

Requires Digest and Signature headers.

Production

Requires Two valid EV SSL certificates from an accepted CA.

One for mTLS, and
another for Signing.



Rabobank servers use EV SSL certificates (e.g., api.rabobank.nl).

Requires Digest and Signature headers.

Digest and HTTP Signature headers

Digest and HTTP Signature headers are mandatory for all requests and ensure message integrity and authenticity.

You should include the following headers in your request:

  1. date - Must contain the current HTTP date in RFC 7231 format.
  2. digest - Hash of the request body using SHA-512 (or SHA-256). For Bulk payments, hash of the request body including the metadata.
  3. x-request-id - Unique UUID for each request to ensure traceability.
  4. Signature - Contains the signing string of selected headers using your private key.
  5. Signature-Certificate - Public certificate stripped of tags and line breaks, used to verify the signature.

Additional headers

This header is additional for PSD2 - Single and Bulk payments:

  • tpp-redirect-uri - Mandatory for HTTP POST requests.

Set up the following headers:

Date Header

The date is the HTTP-date in RFC 7231 format.

Mon, 15 Dec 2025 13:39:29 GMT

Digest Header

Digest ensures the request body hasn’t been altered in transit.

Steps:

  1. Use the exact sequence for the HTTP request body as sent (Do not add any extra spaces or line breaks).
    For Bulk payments: Take the body of the request and include the metadata of the file. Example values are present here.
  2. Compute the binary hash using SHA-512 or SHA-256 hashing algorithm.
    📘

    SHA‑256 and SHA‑512 are two hash functions from the SHA‑2 family. They work the same way but differ mainly in output size, security level, and performance.
    Both are considered cryptographically secure for hashing request bodies. They differ mainly in performance and strength depending on the hardware and requirements.

  3. Base64-encode the hash.
  4. Add the header:
    digest: sha-512=<Base64Value>

Example:

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

sha-512=z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==

X-Request-ID Header

This is a UUID for each request to ensure traceability.

Example:

x-request-id: f9b311bb-b1e7-4ec8-b276-d1c6e38f78db

Signature Header

The Signature header proves the authenticity of your request by signing critical headers with your private key.

Components:

  • keyId - The serial number of the certificate (Integer format).
  • algorithm - Algorithm used for hashing: rsa-sha512 or rsa-sha256
    👍

    RSA on its own is just a public/private key algorithm. When you create a signature with RSA, you must also choose a hashing algorithm—that’s where RSA‑SHA256 and RSA‑SHA512 come in.

  • headers - The list of headers included in the signature.
  • signature - The Base64-encoded RSA signature of the signing string.

Steps to build the signature header:

  1. Retrieve the Certificate Serial Number from the EV SSL certificate and convert it to an integer format:
    openssl x509 -in cert.pem -noout -serial | cut -d'=' -f2 | tr -d ':' | awk '{print strtonum("0x"$0)}'
  2. Choose the algorithm, you can use rsa-512 or rsa-256.
  3. Define the headers:
    • All lowercase
    • Separated by a space
    • In the same order as in the signing string.
    headers="date digest x-request-id"
  4. Create the signing string. Concatenate the Date, Digest and X-Request-ID separated by line breaks \n to create the signing string. For example:
    date: <current HTTP date>  
    digest: sha-512=<Base64Digest> 
    x-request-id: <uuid>
    Optionally, add tpp-redirect-uri.
  5. Sign the signing string using:
    • rsa-sha512 or rsa-sha256 and your private key.
    • Base64encode the output. The output should look like this:
    signature: keyId="<base64 cert>",algorithm="rsa-sha512",headers="date digest x-request-id",signature="<Base64-signed-string>"
    Example:
    The resulting signature header using our example private key:
    signature: keyId="1523433508",algorithm="rsa-sha512",headers="date digest x-request-id",signature="aS6D/cKMgEnAES6yVpKs2AjkxbPReF760F8hDHXLZ2ic0OFI84eIjRl2DYLJc4EPjNcsYvxaSyPypJvMnOiU3gnj4vrs/PrR5A/x2COA9fe6OwJThfLTPxeXoRxxw6sGEjRCrF06sY/IKmRPdp4AjVzYfBeAeshjzr/icghp/Zzi4DOOBp+39bdWUJDCVHM9m0V/LRM18xdJtBKssP6Wzy5wncCmk7fHm1nLD31N+SARYcPuMutGHgIwQrNB/czR3e6g7o+2C8J0nC0kPM95VBWAyChTOqPsvcBHKcxreZe9aNywclpVOtXJit05q3O3PfLvJHH3QoPTRpzsP38pOw=="

Signature-Certificate Header

To verify your signature, Rabobank requires you to send your public certificate in a request header.

Steps:

  1. Take your PEM-encoded certificate.
  2. Remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----tags.
  3. Remove all line breaks so the certificate becomes a single continuous string.
  4. Add it to the header:
    Signature-Certificate: <PEM certificate without tags or line breaks>

Example:
The result with our example certificate should be:

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