If you encounter Invalid digest error (error.digest.invalid), please consider the following:
- Check our documentation regarding Digest calculation:
Example code: eIDAS signature creation (Access Authorization API)
- Download Postman collections and test your request:
Postman and Swagger files (Nordea API Market)
- The whole request body should be present in the digest. Refer to:
Redirect Access Authorization (Access Authorization API)
Authentication with eIDAS certificate (Access Authorization API)
- Digest should be calculated based on a request body in JSON format (as it is sent to Nordea in the request). Converting the request body into the string is incorrect
-
When making requests to Nordea Open Banking APIs, please ensure that SHA-256 algorithm is used
- To correctly calculate a digest it's necessary to operate on bytes
- The payload-rich requests require a Digest header to be present and mentioned in the Signature header message elements. Refer to:
Authentication with eIDAS certificate (Access Authorization API)
Then the Signature header should look as follows:
'Signature': 'keyId="<client_id>",algorithm="rsa-sha256",headers="(request-target) x-nordea-originating-host x-nordea-originating-date content-type digest",signature="<encoded_signature_message>"'
- Digest should be calculated on the same values as in the request payload and the scope value should be a list (not a string). Refer to:
Redirect Access Authorization (Access Authorization API)
- (Sandbox) When a signature is used as 'SKIP_SIGNATURE_VALIDATION_FOR_SANDBOX' you can remove digest header from the request and still the request will go through by skipping the signature related validation
- Check if the payload format is a valid JSON
- (Corporate Access Authorization) Digest and Signature headers values are not hardcoded. These values are generated according to:
How do I sign my API requests? (Corporate Access Authorization API)
Postman collection includes the logic for generating these values as a pre-request script:
Creating signature header with Postman (Corporate Access Authorization API)
-
(Corporate Access Authorization) Content-type header in /corporate/v2/authorize endpoint is application/json and therefore string used to create digest should be in the form of JSON body of the request, for example:
{"scope": ["ACCOUNTS_BROADBAND"], "duration": 3600, "agreement_number": "123456789012"}
-
Check Content-Length of request body for unwanted spaces/tabs (e.g. one additional space will generate a different digest)
- Remember to use a proper endpoint for a token exchange. Refer to:
Business Access Authorization API
Corporate Access Authorization API
- When creating digest it is important to have an alphabetical order in the Payload:
How can I get started signing with eIDAS?
- If you use Python requests, make sure arrays are formatted correctly in the request body and the scope is passed as a [string]
FAQ
-
Do you have any C# code available for creating a digest header?
We do not have an example in C#, but to help you verify your code please compare your results with the example we created by hashing the word "test":
n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=
It was created using SHA-256 algorithm. As long as you provide the same input ('test') to your digest function, it should return exactly the same output as in this example.
-
Does the digest header need to be SHA-256 hashed and then Base64 encoded? We used SHA-256 (for example on: https://emn178.github.io/online-tools/sha256.html) as a comparison to our own code and with the word “test” it returns:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
which is Base64 encoded into:
OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZjMTViMGYwMGEwOA==
The hash before encoding as Base64:
9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
is correct but these are bytes in hexadecimal format and you have incorrectly treated it as a text and Base64 encoded it.
As an example, please consider this page: https://base64.guru/converter/encode/hex. It understands that you're encoding bytes in hex format and provides a valid Base64 encoded hash:
n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg=
If you try this one instead: https://base64.guru/converter/encode/text you will see that it produces:
OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZjMTViMGYwMGEwOA==
which matches your result.
To summarize: beginning of the hash '9f' (or '9F' as it's usually displayed) is a byte representing number 237. But text '9f' has different meaning (and '9F' yet another one). To correctly calculate digest it's necessary to operate on bytes (that complexity is usually hidden behind a library or a tool you are using).