BankID Proof

Proof of BankID Authentication

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). The ID token shows that a user has been successfully authenticated by the BankID OIDC Authentication Server. However, the ID token is not sufficient to prove that a BankID Netcentric or BankID on Mobile transaction has been performed by the end-user. For merchants and banks that require a stronger and long-term proof of BankID Netcentric or BankID on Mobile authentication, BankID OIDC offers BankID Proof.

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, the merchant 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

Access to BankID Proof can be requested by BankID partners and banks by using our support desks.

The BankID Proof information will be included in the bankid_proof token in the authorization code token response if it was requested using the bankid_proof scope.

Content of BankID Proof

The bankid_proof token is a JSON Web Signature (JWS) signed by the BankID OIDC Authentication Server 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 challenged 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 (BID/BIM) and if the merchant provided a nonce value in the original 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 Netcentric, 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
Authentication methodID token nonceSignature Verifiation calculation (mesServer Challenge Payload
BankID Netcentric (BID) w/nonce0d6b73af-890c-4494-b632-c5827a804e86

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:

  • Check that
    hashClientNonce == sha256(utf8GetBytes(idTokenNonce))
  • Check that
    hashSigned == sha256(b64dec(internalNonce) + hashClientNonce)
  • Check that
    hashSigned equals the message digest in the end user signature
"serverChallenge": {
    "hashClientNonce": "+vC+eDrHXsjxogwmjJ7M1Kahummb2+K8DHODAEK0ZkI=",
    "internalNonce": "EBgPFbDvXcsbXch2Ed3U4dvmBbQ="
}

BankID Netcentric (BID) w/o nonce

(warning) Not recommended:
Merchant should always provide a unique nonce.

(not provided)

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:

  • Check that
    hashSigned == sha256(b64dec(internalNonce)) 
  • Check that
    hashSigned equals the message digest in the end user signature
"serverChallenge": {
    "internalNonce": "EBgPFbDvXcsbXch2Ed3U4dvmBbQ="
}
BankID on Mobile(irrelevant)

The message digest in the end user signature should equal:

sha256(b64dec(gsmChallenge))

  "serverChallenge": {
    "gsmChallenge": "..."
  }

Certificate revocation check

The merchant must check the revocation status of the end-user certificate using the end-user OCSP response.

Note: If the merchant certificate used in the authentication 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.

BankID Proof for signing

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 for 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 the endUserSignature, endUserOcsp and 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.