Skip to content

4.1 Wallet Account Registration

This flow describes the wallet registration process as part of the broader wallet activation as introduced here.

Design Decisions

In the wallet registration process, the Wallet Instance (WI) first proves its authenticity and integrity to the Wallet Backend (WB) and then establishes a hardware-bound key pair for subsequent authentication of the Wallet Instance to the Wallet Backend. The Wallet Backend responds with a Wallet Instance identifier and stores it alongside the corresponding public key in its database.

The Wallet Instance begins the wallet registration by requesting a challenge from the Wallet Backend, this challenge is part of the replay attacks protection and ensures the freshness of the request. The Wallet Instance uses app attestations from the mobile platform to prove its authenticity and integrity utilizing this challenge. The Wallet Backend verifies this proof using attestation keys provided by the Mobile Platform Provider (MPP). To limit costs for obtaining app attestations from the MPP, the Wallet Instance enforces rate limits, causing the process to fail if the limit is exceeded.

Additionally, the Wallet Instance generates a hardware-bound key pair on the mobile device and transmits the public key to the Wallet Backend. This key acts as a possession factor for one-factor authentication of the Wallet Instance to the Wallet Backend. The key generation must utilize the most secure key store available on the mobile device, such as Secure Element, StrongBox, SecureEnclave or TEE. A proof of possession for the private key is done by signing the challenge.

The Wallet Backend does not need to store any session data or state related to a specific Wallet Instance during the registration process. Instead, the process relies on cryptographically signed ("self-contained") challenges to verify the authenticity of the Wallet Instance.

4.2.1 Wallet Account Registration

This section described the data flow of the wallet registration in a sequence diagram and a more detailed table. Artifacts in italics are further explained in the data register chapter

Sequence Diagram

Wallet RegistrationWallet RegistrationWallet Instance . App .WI.Wallet Backend .WB.WB account databaseWallet Instance / App (WI)Wallet Instance / App (WI)Wallet Backend (WB)Wallet Backend (WB)WB account databaseWB account database(001)[TLS] </challengeEndpoint>()(002)generate wb_auth_challenge:sign(nonce,timestamp)wb_challenge_symk(003)[TLS] <wb_auth_challenge>(004)generate wi_wb_auth_pop:sign(wb_auth_challenge,mdvm_token)wi_mdvm_auth_prvk(005)request registration:[TLS] </registrationEndpoint>(wi_wb_auth_pop)(006)verify mdvm_token to ensure deviceauthenticity and integrity(007)match wi_mdvm_auth_pubkcontained in wi_wb_auth_pop andmdvm_token(008)verify wi_wb_auth_pop using includedwb_auth_challenge(009)persist new wallet instance recordwith wb_wi_id andwi_mdvm_auth_pubk(010)registration complete:[TLS] wb_wi_id(011)store wb_wi_id

Detailed Description

No Description
001 - 003 The WI requests a challenge from the WB challenge endpoint using an HTTP POST request, the request is unauthenticated. The WB generates a JSON structure containing a random nonce and a timestamp of the current time and MACs it using a symmetric key (wb_challenge_symk) as a JSON Web Token (JWT), the resulting structure is the wb_auth_challenge. The WB responds to the WI with the wb_auth_challenge in the HTTP payload. The WI uses the challenge as a opaque string and does not evaluate the JWT claims. The WB does not store the challenge after creation, thus the operation is stateless.
004 The WI re-uses the hardware-bound, attested cryptographic key pair (wi_mdvm_auth_prvk, wi_mdvm_auth_pubk) as the possession factor towards the WB and computes a proof of possession by signing the wb_auth_challenge for freshness and to enable replay protection and the mdvm_token to ensure authenticity and integrity of the WI with wi_mdvm_auth_prvk and encoding it as a JSON Web Token (JWT). The resulting structure is called wi_wb_auth_pop.
005 The WI requests the WB to perform the registration by sending the proof of possession (wi_wb_auth_pop). The request is unauthenticated (as WB does not know the WI yet at registration).
006 - 008 The WB verifies the received mdvm_token with mdvm_attestation_pubk for authenticity and integrity and checks that it is still valid and was issued recently. The WB verifies the received proof of possession for the WI's possession factor (wi_wb_auth_pop) using the included wi_mdvm_auth_pubk with the signed challenge (wb_auth_challenge). The WB verifies the self-contained wb_auth_challenge using its symmetric key (wb_challenge_symk) and validating that the timestamp is within a valid time interval as specified in the token lifecycle section of the cryptography chapter. Lastly, the WB verifies that the used key wi_mdvm_auth_pubk is the same in wi_wb_auth_pop and mdvm_token.
009 The WB generates an Wallet Instance identifier wb_wi_id and stores the combination of wb_wi_id and wi_mdvm_auth_pubk in its database to register the new WI.
010 The WB responds with the generated Wallet Instance identifier wb_wi_id to the WI.
011 The WI stores the received Wallet Instance identifier wb_wi_id.

Wallet Challenge JWT

The wb_auth_challenge encapsulates a verifiable challenge, that is generated and verified by the Wallet Backend. As the producer and consumer is the Wallet Backend, a MAC key wb_challenge_symk is used for efficiency reasons to ensure the integrity and authenticity of the challenge.

The wb_auth_challenge contains:

  • JOSE Header typ: as recommended by JWT BCP
  • JOSE Header alg: indicating HMAC-SHA256 as MAC algorithm
  • JOSE Header kid: containing a key identifier for wb_challenge_symk
  • JWT Claim iss: containing the the name of service which issued the challenge
  • JWT Claim nonce: containing at least 128 bits of random
  • JWT Claim iat current time, indicating the issuance date

Below is a non-normative example of a wb_auth_challenge:

Header

{
  "typ": "auth-challenge+jwt",
  "alg": "HS256",
  "kid": "1"
}
Payload
{
  "iss": "german-national-wallet:wallet:prod",
  "nonce": "564edacb-ad81-420c-a74e-6cfbaa713d48",
  "iat": 1726214250
}

Signed by wb_challenge_symk