BankID Proof¶
What is BankID Proof?¶
The ID token contains information about the authentication of an end-user, such as when the end-user was authenticated (auth_time
),
who the end-user is (e.g. bankid_altsub
, nnin
, name
) and what authentication method was used (amr
).
In short, the ID token shows that a user has been successfully authenticated by the BankID OIDC Authentication Server.
However, the ID token is not sufficient proof that a BankID High or BankID Substantial transaction has been performed by the end-user.
For merchants and banks that require a stronger, long-term proof of a BankID transaction, we offer "BankID Proof".
What is required to prove a BankID transaction?¶
Authentication with BankID involves that the end-user signs a randomly generated challenge. The result is a CMS (Cryptographic Message Syntax) signature which includes the end-user's certificate.
In order to prove that a BankID authentication has been performed, you must be able to provide:
- The challenge signed by the end-user
- The end-user's signature
- The end-user's certificate
- The OCSP (Online Certificate Status Protocol) response for the end-user's certificate
How to retrieve BankID Proof?¶
To retrieve the BankID Proof after a successful authentication you must provide the bankid_proof
scope in the list
of scopes to the authorize endpoint.
Access to this scope can be requested by BankID partners and banks by using our support desks.
The bankid_proof
token is a JSON Web Signature (JWS) signed by the BankID OIDC Provider and included in the token response.
Example of BankID Proof JWS payload¶
{
"endUserOcsp": "MIIHEAoBAK...",
"endUserSignature": "MIAGCSqGSI...",
"hashSigned": "xWyTcDzLiB9loBWIClbMnu7ganTPw6Q7gFTo80R+kgU=",
"serverChallenge": {
"hashClientNonce": "+vC+eDrHXsjxogwmjJ7M1Kahummb2+K8DHODAEK0ZkI=",
"internalNonce": "EBgPFbDvXcsbXch2Ed3U4dvmBbQ="
}
}
The BankID proof for authentication contains:
- endUserSignature: The end-user's signature including the end-user's certificate
- endUserOcsp: The OCSP response for the end-user's certificate
- hashSigned: The challenge signed by the user. Provided for convenience, but should be extracted from the end-user's signature.
- serverChallenge: Information used to generate the challenge signed by the end-user. The content and method of deriving
hashSigned
depends on authentication method and if you provided a nonce value in the original authentication request.
Include nonce in authentication request
It is strongly advised that all merchants that use BankID proof provides the nonce
parameter in the original authentication request as it will be used in the challenge generation for BankID High, indirectly binding the ID token to the bankid_proof
token.
Message digest verification¶
The following table shows how the message digest in the end user signature is calculated. This value should equal hashSigned
, but the
merchant must always retrieve this from the messageDigest signedAttribute in the SignerInfos of the end user signature.
Please see RFC5652: Signature Verification Process for details.
The following functions are used:
- base64enc: Base64 encode
- base64dec: Base64 decode
- sha256: Generate hash value / message digest using the SHA-256 hash function.
- idTokenNonce: Should be the same as the nonce parameter passed to the original authentication request
- utf8GetBytes: Convert UTF-8 string to byte array
BankID High (BID) with nonce¶
Signature Verifiation calculation¶
The message digest in the end user signature should equal:
sha256(b64dec(internalNonce) + sha256(utf8GetBytes(idTokenNonce)))
If there is a mismatch, the following can be used to find the issue:
hashClientNonce == sha256(utf8GetBytes(idTokenNonce))
hashSigned == sha256(b64dec(internalNonce) + hashClientNonce)
Also check that hashSigned equals the message digest in the end user signature.
Server challenge payload¶
{
"serverChallenge": {
"hashClientNonce": "+vC+eDrHXsjxogwmjJ7M1Kahummb2+K8DHODAEK0ZkI=",
"internalNonce": "EBgPFbDvXcsbXch2Ed3U4dvmBbQ="
}
}
BankID High without nonce¶
Signature Verifiation calculation¶
The message digest in the end user signature should equal:
sha256(b64dec(internalNonce))
If there is a mismatch, the following can be used to find the issue:
hashSigned == sha256(b64dec(internalNonce))
Check that hashSigned equals the message digest in the end user signature.
Server challenge payload¶
Certificate revocation check¶
You must check the revocation status of the end-user certificate using the end-user OCSP response.
Note: If your certificate has access to NNIN, the NNIN will always be included in the end-user's OCSP response with OID (object identifier) 2.16.578.1.16.3.2.
What about BankID Proof for signing scenarios?¶
Simple sign flow¶
If the bankid_proof
scope is provided when starting a simple sign flow, the sign_result claim will be omitted as all relevant information will be provided in the bankid_proof
token.
Example of BankID Proof JWS payload:¶
This example is from a simple sign with the text "This is a simple sign text æøå ÆØÅ"
{
"merchantSignature": "MIAGCSqGSI...",
"merchantOcsp": "MIIG3woBAK...",
"endUserOcsp": "MIIHEAoBAK...",
"hashOriginal": "iuGj0XD14fzQ0fnNBti7llGO2rFufjn9ZCzhkS1ns1o=",
"endUserSignature": "MIAGCSqGSI...",
"hashSigned": "kTkeKcvPAs1jImcFk4PRv6hecdDi1bJ3EcGYvi7/xLE="
}
The BankID proof payload contains:
- endUserSignature: The end-user's signature including the end-user's certificate
- endUserOcsp: The OCSP response for the end-user's certificate
- merchantSignature: The merchant's signature including the merchant's certificate
- merchantOcsp: The OCSP response for the merchant's certificate
- hashOriginal: Hash over the original sign_txt requested by the merchant
- hashSigned: The challenged signed by the user. Provided for convenience, but should be extracted from the end-user's signature. Note that hashSigned might be different from hashOriginal if the text contains characters that have different byte values in UTF-8 and ISO-8859-1 or mobile charsets (i.e. GSM).
Full sign flow¶
If the bankid_proof
scope is provided when starting a full sign flow (i.e. SEID-SDO or PAdES), it will contain:
endUserSignature
endUserOcsp
hashSigned
for the first signed document.
This could potentially be used to bind a user authentication with a sign process, but the signature data should be retrieved from the SignDoc Resource Server response and not the bankid_proof
token.