Signed Tokens
Following well established OpenID Connect standards, BankID signs all Tokens issued:
Asymmetric keys used for signing is exposed in the JWKs endpoint. These keys may change, so make sure you keep them up-to-date (every 24 hours).
You must validate signatures and compare with the published root certificate as part of token validation to ensure that tokens are not tampered with after being issued by the OIDC Provider from BankID.
In addition, this way you can always guarantee that the origin of the Tokens are in fact BankID, and not a potential "man-in-the-middle" actor.
These steps are required to securely validate a JWS Token (like ID Token) from BankID:
- Retrieve all JWK entries with "use": "sig" that BankID exposes from the JWKs endpoint.
- Find the key used to sign the JWS Token by extracting the kid value of the JWS Header.
- Match the kid value with the JWK entries from step 1. and extract the public key value and certificate chain (x5c).
- Validate the origin of the key by verifying it's complete certificate chain (x5c) with our published root certificate.
- Validate the JWS token using the key.
- Using a secure and community provided library to validate JWS tokens is highly recommended.
Signed Authorization Requests
BankID OIDC can support signing incoming Authorization Requests:
- request authorize parameter
- private_key_jwt client_assertion object
To support this, a jwks_uri must be registered for the given merchant (OIDC Client), so BankID can retrieve validation keys.
Contact us for more information.
Encrypted Authorization Requests
Encryption of parameters containing personal information may be mandatory in the future.
BankID supports encryption of incoming Authorization Requests through:
- login_hint encryption (deprecated)
- request authorize parameter
This can be useful in order to ensure personal information (for example through login_hint) is not leaked in the browser history or URL.
The login_hint encryption is deprecated as it is being replaced by the standard encrypted request parameter.
Asymmetric Keys used for encryption in JWKs are all marked with
"use":"enc".
Encryption algorithms supported are:
login_hint | request parameter | ||
Alg | Enc | Alg | Enc |
---|---|---|---|
ECDH-ES | A128GCM | RSA1_5 | See openid-configuration document |
RSA-OAEP | A128CBC-HS256 | RSA-OAEP | See openid-configuration document |
RSA-OAEP-256 | A128CBC-HS256 | RSA-OAEP-256 | See openid-configuration document |
The encrypted login_hint should be formatted as a JWE Compact Serialization. The ciphertext is the encrypted plaintext login_hint.
The encrypted request parameter should be formatted as a JWE Compact Serialization. The ciphertext is the request parameter as a signed JWT
Example
A typical login hint:
login_hint=BID:14025800177
will using the encryption key in the Jwk example, be:
login_hint=eyJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJjSm1XTWtrcXlWUDYtbFcya3hoSElUZG5oNkR1MkNzUklZZzBja3lXdVdBIiwieSI6IlRpbDROMFlGNWFSNnJJUWpHRjY4cWRkQ2ZfcDJuVmJCM1RMY2U2bDNxVlkifSwia2lkIjoiZW5jcnlwdGtleSIsImVuYyI6IkExMjhHQ00iLCJhbGciOiJFQ0RILUVTIn0..DzbBsb5mQSl-S-zG.-hL1oyZNRrqkp4UJHxX_.Q0n47mXdkmAoDfSqu-vkEg
The header part of the JWE object is in this case:
{ "epk": { "kty": "EC", "crv": "P-256", "x": "cJmWMkkqyVP6-lW2kxhHITdnh6Du2CsRIYg0ckyWuWA", "y": "Til4N0YF5aR6rIQjGF68qddCf_p2nVbB3TLce6l3qVY" }, "kid": "encryptkey", "enc": "A128GCM", "alg": "ECDH-ES" }
BankID OIDC provider will use the kid value to extract the correct key for decryption. If the kid value is not set, the decryption will fail.
The message to be encrypted is not JSON, it is simply:
BID:14025800177