Skip to content

Issuance of Wallet Instance Attestation (WIA)

This flow describes the process of issuing a wallet attestation (WIA) as introduced here in the blueprint.

Design Decisions

In the WIA issuance process, the WI uses the established one-factor authentication from the registration process to request a fresh issuance of Wallet Instance Attestations (WIAs).

The process uses app attestations of Platform Attestation Provider (PAP) for every issuance to get assurance about the integrity of the mobile app and its device. 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. The key generation must utilize the most secure key store available on the mobile device, such as a Secure Element, StrongBox, SecureEnclave or TEE. A proof of possession for the private key is done by signing the challenge.

The Wallet Provider Backend (WB) analyses the provided app attestation and does additional checks on vulnerability management and user-initiated revocation before issuing and returning a batch of one-time WIAs. The WB issues the WIA as a JWT as defined in attestation-based client authentication, using x509 certificate as trust mechanism to sign the WIA. The WI provides multiple keys and proof of possessions and the WB issues multiple corresponding WIAs, such that they can be used in a one-time use by the WI (which prevents linkability).

We decided to use stateless challenges instead of stateful challenges stored in the backend, as binding using wi_wia_pop for the app attestation challenge is sufficiently secure to protect against replay attacks.

ToDo

  • update design considerations text to include mdvm token
  • add Android key attestations for wi_wia_prvk[]
  • add rate limiting/replay attack detection based on wb_auth_challenge and wb_wi_id

Data Flow

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

Issuance of Wallet Instance Attestation (WIA)Issuance of Wallet Instance Attestation (WIA)Wallet Backend .WB.Wallet Instance . App .WI.Mobile Device Vulnerability Management .MDVM.Wallet Backend (WB)Wallet Backend (WB)Wallet Instance / App (WI)Wallet Instance / App (WI)Mobile Device Vulnerability Management (MDVM)Mobile Device Vulnerability Management (MDVM)(001)renewal of mdvm_token(002)[TLS] </challengeEndpoint>()(003)generate wb_auth_challenge:sign(nonce, timestamp)wb_mac_symk(004)[TLS] <wb_auth_challenge>(005)generate client attestation key pair(wi_wia_prvk, wi_wia_pubk)(006)generate wi_wb_auth_pop:sign(wb_wi_id, wb_auth_challenge,mdvm_token,wi_wia_pubk)wi_mdvm_auth_prvk,wi_wia_prvk(007)[TLS] </wiaEndpoint>(wi_wb_auth_pop)(008)verify wb_auth_challenge fromwi_wb_auth_pop using wb_mac_symk(009)verify mdvm_token withmdvm_attestation_pubk to ensuredevice authenticity and integrity ofthe WI(010)lookup wi_mdvm_auth_pubk from thedatabase using wb_wi_id(011)match wi_mdvm_auth_pubkcontained in mdvm_token withdatabase(012)verify wi_wb_auth_pop usingwi_mdvm_auth_pubk(013)verify wi_wb_auth_pop using includedwi_wia_pubk(014)check if the wallet instance is revokedby the user(015)generate wb_wia:(wi_wia_pubk)wb_wia_auth_prvk(016)[TLS] wb_wia

Detailed Description

No Description
001 The WI determines if its most recent mdvm_token is still valid. If the mdvm_token is not up-to-date, the WI may fetch a fresh one from the MDVM endpoint using the renewal flow for either Android or iOS.
002 - 004 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_mac_symk) as a JSON Web Token (JWT), the resulting structure is the wb_auth_challenge. The MDVM responds to the WI with the wb_auth_challenge in the HTTP payload. The WI uses the challenge as a transparent string and does not evaluate the JWT claims. The WB does not store the challenge after creation, thus the operation is stateless.
005 The WI generates a a new hardware-bound key pair (wi_wia_prvk,wi_wia_pubk) which is used as the client attestation key for the wallet attestation (WIA). The WI must leverage the most secure, local key storage available, i.e. a Secure Element, StrongBox, SecureEnclave or TEE. The key must have sufficient security, information on algorithms and key lengths can be found in the cryptography chapter.
006 The WI computes a proof of possession by signing the payload of wb_wi_id for identification, wb_auth_challenge for freshness and to enable replay protection, the mdvm_token to ensure authenticity and integrity of the WI and the client attestation public key wi_wia_pubk with
  • the possession factor wi_mdvm_auth_prvk
  • client attestation private key wi_wia_prvk
and encodes it as a JSON Web Signature (JWS) in JSON Serialization. The resulting structure is called wi_wb_auth_pop.
007 The WI requests the WB to issue a WIA by sending the proof of possession (wi_wb_auth_pop) for the one-factor authentication including wi_wia_pubk to be used as a client attestation public key for the WIA. The request is authenticated.
008 The WB verifies the self-contained wb_auth_challenge included in the wi_wb_auth_pop using its symmetric key (wb_mac_symk) and validating that the timestamp is within a valid time interval of 0 minute to +5 minutes. This step ensures replay protection beyond the valid time interval of the challenge.
009 - 012 The WB validates the security posture of the WI by verifying the mdvm_token with mdvm_attestation_pubk and checks that it is still valid. The WB has a trusted, out-of-band mechanism towards the MDVM to fetch the valid mdvm_attestation_pubk. The WB fetches the public key for the possession factor wi_wb_auth_pubk from the database using the provided account identifier wb_account_id included in wi_wb_auth_pop. The WB verifies the signature of the received proof of possession (wi_wb_auth_pop) for the WI's possession factor using wi_mdvm_auth_pubk from the mdvm_token. Lastly, the WB verifies that the used key wi_mdvm_auth_pubk is the same in mdvm_token and in the database. The database lookup is not subject to prevention of distributed denial of service attacks, as these attacks need to be mitigated further up in the infrastructure layer.
013 The WB verifies the second signature of proof of possession wi_wb_auth_pop using using the included wi_wia_pubk.
014 The WB does additional checks on the WI and its user account to validate that the user did not revoke his WI.
015 The WB generates a Wallet Instance Attestation wb_wia for the provided public key wi_wia_pubk and signs it using its wb_wia_auth_prvk that is associated on a trust list.
016 The WB returns the Wallet Instance Attestations wb_wia to the WI.

Wallet Challenge JWT

Defined in Wallet Registration

Proof of Possession JWT for Authentication

The wi_wb_auth_pop is a possession-based authentication factor of the Wallet App, that creates a proof of the wi_wb_auth_prvk over the wb_auth_challenge.

The wi_wb_auth_pop contains:

  • JOSE Header typ as recommended by JWT BCP
  • JOSE Header alg indicating ECDSA NIST P-256
  • JWT Claim wb_wi_id containing the serialized wb_wi_id
  • JWT Claim wb_auth_challenge containing the serialized wb_auth_challenge
  • JWT Claim mdvm_token containing the serialized mdvm_token
  • JWT Claim wi_wia_pubk containing the serialized wi_wia_pubk
  • JWT Claim aud referencing the URL of the Wallet Provider Backend

Note: There is no jti parameter for potential enhanced replay protection, as we can reuse the wb_auth_challenge for this purpose. There is also no iat or exp parameter, because the wb_auth_challenge already includes a trusted timestamp. There is also no iat or exp parameter, which is added by the WI, because the wb_auth_challenge already includes a trusted timestamp.

Below is a non-normative example of a wi_wb_auth_pop:

Protected headers:

{
  "typ": "wi-wb-auth-pop+jwt",
  "alg": "ES256"
}
Payload:
{
  "wb_wi_id": "3e8ba9be-78d9-4ed3-996a-a9d4d72ce414",
  "wb_auth_challenge": "eyJ0eXAiOiJ3Yi1hdXRoLWNoYWxsZW5nZStqd3QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MzgzMTQ4NzQsIm5vbmNlIjoiZmEwYTMxMGUtOTFkMi00NjFjLWJhMDAtY2MzNWE5OTVmMTY2IiwiaWF0IjoxNzM4MzExMjc0fQ.7QpBVKvwuukioYhLX402ay-DwTv5H3x-hhovev72i58",
  "mdvm_token": "...",
  "wi_wia_pubk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "32jtyqhBGxKxqeihaRsmW449oB9hcMUSgNCxDjHfADo",
      "y": "3ARvwMghvfz7zAcGEdwQj2h5DQU64BezdaSthn7qJzk"
    }
  "aud": "https://wallet-provider-backend.eudi-wallet.de"
}

Signed by wi_wb_auth_prvk

Wallet Instance Attestation (WIA)

The wb_wia is a signed attestation of the Wallet Provider backend, attesting to the validity of the Wallet Instance towards Issuers and Relying Parties. The format is described in Section 5.1 of attestation-based client authentication.

In accordance to the rules defined in the draft, the wb_wia contains:

  • JOSE Header typ as recommended by JWT BCP
  • JOSE Header alg indicating ECDSA NIST P-256
  • JOSE Header x5c containing the x509 certificate chain of the Wallet Provider
  • JWT Claim sub: referencing the client_id of the Wallet Provider Backend
  • JWT Claim exp: current time + expiration time interval, indicating the expiration data of the WIA
  • JWT Claim cnf: containing the serialized wi_wia_pubk
  • JWT Claim iat: current time, indicating the issuance date of the WIA (optional)

Below is a non-normative example of a wb_wia:

Protected headers:

{
  "typ": "oauth-client-attestation+jwt",
  "alg": "ES256",
  "x5c": [
    "MIIBETCBuQIJAM6k5TM9MgHEMAkGByqGSM49BAEwEjEQMA4GA1UEAwwHdGVzdC5kZTAeFw0yNDExMTExMjMwMTRaFw0yNTExMTExMjMwMTRaMBIxEDAOBgNVBAMMB3Rlc3QuZGUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATQivHxcyv56XIfjt6EeyekabQ44oXSvplQXwE42c5SKheiZyhKfjhATMdpNQKV+2WnNX28Dwlv/mBQkA2pPe98MAkGByqGSM49BAEDSAAwRQIgcn7PP74vJ82nUxVQA4nt++IzWK+xYX2jGe9oh/5R9CICIQCsCjry+BL5biHKY6Pp8hUSsGqpMCV2uza/lhq4C4RoWg=="
  ]
}
Payload:
{
  "sub": "de.bmi.eudi-wallet.wallet-provider-backend",
  "cnf": {
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "32jtyqhBGxKxqeihaRsmW449oB9hcMUSgNCxDjHfADo",
      "y": "3ARvwMghvfz7zAcGEdwQj2h5DQU64BezdaSthn7qJzk"
    }
  },
  "iat": 1750742508,
  "exp": 1750828908
}

Signed by wb_wia_auth_prvk

Proof of Possession JWT for Wallet Instance Attestation (WIA)

The wi_wia_pop is a proof of possession signed by the Wallet Instance, attesting to the possession and usage of the WIA towards the Wallet Provider Backend. The format is aligned with Section 5.2 of attestation-based client authentication, but contains slight differences.

In accordance to the rules defined in the draft, the wi_wia_pop contains:

  • JOSE Header typ as recommended by JWT BCP
  • JOSE Header alg indicating ECDSA NIST P-256
  • JOSE Header jwk containing the serialized wi_wia_pubk
  • JWT Claim aud referencing the URL of the Wallet Provider Backend
  • JWT Claim jti containing a UUID
  • JWT Claim iat: current time, indicating the issuance date of the PoP
  • JWT Claim wb_auth_challenge containing the serialized wb_auth_challenge

Note: The Wallet Backend is using the challenge for replay protection instead of jti, but the draft of attestation-based client authentication requires jti to be present in any case.

Below is a non-normative example of a wi_wia_pop:

Protected headers:

{
  "typ": "oauth-client-attestation-pop+jwt",
  "alg": "ES256",
  "jwk": {
    "kty": "EC",
    "crv": "P-256",
    "x": "32jtyqhBGxKxqeihaRsmW449oB9hcMUSgNCxDjHfADo",
    "y": "3ARvwMghvfz7zAcGEdwQj2h5DQU64BezdaSthn7qJzk"
  }
}
Payload:
{
  "aud": "https://wallet-provider-backend.eudi-wallet.de",
  "jti": "d25d00ab-552b-46fc-ae19-98f440f25064",
  "iat": 1750742508,
  "wb_auth_challenge": "eyJ0eXAiOiJ3Yi1hdXRoLWNoYWxsZW5nZStqd3QiLCJhbGciOiJIUzI1NiJ9.eyJub25jZSI6IjhjM2YyODM4LTU1Y2QtNGE0MC1iOTg5LWEzMzYyNDhkOGNlOCIsImlhdCI6MTc1MDc0MjUwOH0.VD0P5y2EZbut0_JxCd_nwo0RNDZhndzO7M2xWzZ7xyA"
}

Signed by wi_wia_pop_prvk