Comparison with the German Model

This page compares the Secure Keystore with the remote WSCA of the German EUDI wallet, as described in the wallet development documentation of the German Federal Ministry of the Interior (BMI), release 0.18.0. The key custody is the same. What differs is how the user is authorized and the shape of the requests.

The comparison is with the Secure Keystore’s target design, including parts that are not implemented yet (the REST endpoints, the device-key thumbprints and the startup checks of the HSM keys).

What Is the Same

  • The private key is generated in the HSM and leaves it only as a wrapped key: a JWE sealed with AES-256-GCM that carries the owner. The wrapped key lives on the phone, and the HSM stores nothing per user.
  • To sign, the HSM receives only a hash. It restores the key, signs and destroys it. The keystore compares the owner inside the wrapped key with the request.
  • The provider signs the key attestation (in the German model, the wallet trust evidence) with an HSM key, bound to the issuer’s c_nonce. It issues a WIA valid for 10 minutes, with no identifier other than the status index.
  • A compromised Wallet Integration Server cannot sign with a user’s keys, because the keystore itself verifies the device signatures.

What This Design Adds

  • Key purpose in the wrapped key. The German model binds only the owner. Here a credential key can never act as a WIA key or a user-signing key, and the reverse.
  • Device-key thumbprints in the wrapped key. Every key is tied to the device keys of one activation. They are compared with the unit’s stored device keys when a user-signing key signs.
  • Hardened HSM keys, checked at every start: generated-in-HSM attributes, an enforced unwrap template, probes and a self-test. The German documentation does not specify these.
  • End-to-end encryption. In the German model, the wallet talks to the remote WSCA directly. Here the Wallet Integration Server forwards the requests, so the bodies are encrypted for the keystore and the forwarder cannot read them.

Keys

The HSM keys of the two models correspond. The difference is in how the user and the device are authenticated, which in the German model needs keys of its own.

Purpose German model Secure Keystore
Wrap the user’s private keys rwscd_master_key: AES-256 key wrap in the HSM, rotated monthly wrap-user-ecdsa-<n>: AES-256 key wrap in the HSM
Bind the wrapped key rwscd_aead_symk: AES-256-GCM in the HSM, rotated monthly; binds the owner bind-user-ecdsa-<n>: AES-256-GCM in the HSM; binds the owner, the purpose and the device-key thumbprints
Sign key attestations rwscd_wte_auth_prvk: P-256 in the HSM, rotated every 3 months sign-eudi-ecdsa-ka: P-256 in the HSM
Sign wallet instance attestations wpb_wia_auth_prvk: P-256 in the HSM of the wallet provider backend sign-eudi-ecdsa-wia: P-256 in the keystore’s HSM
Authenticate the device Device key wi_mdvm_auth_prvk in the phone’s hardware key store PowerAuth device private keys in the SDK’s vault: ECDSA P-384, plus ML-DSA when hybrid
Authenticate the PIN PIN key wi_rwsca_pin_prvk, derived from the PIN for each PIN session PowerAuth vault unlock, verified by PowerAuth Server
Trust in stored device data PIN public key stored by the WSCA Device public keys stored per unit at registration
Protect PIN sessions and challenges rwscd_pin_symk, rwscd_challenge_symk: HMAC-SHA256 in the HSM None needed: no PIN session and no challenge
WIA key wi_wia_prvk: a fresh key in the phone’s hardware key store, one use Generated in the HSM, kept on the phone as a wrapped key, new per issuance
Refresh-token (DPoP) key rwscd_rt_prvk: a wrapped key from the HSM, valid 2 years Not a keystore key: the DPoP key is a phone key, and the refresh token is bound to the WIA key
Credential key rwscd_pid_device_prvk: a wrapped key from the HSM, one use, 2 months A wrapped key from the HSM, 1 to 16 per batch
User-signing key Not part of the compared documentation A wrapped key from the HSM, one per activation: P-384, plus ML-DSA when hybrid

Evidence per Request

In both models the keystore accepts only evidence that only the device can produce: a signature by a device private key. The German WSCA verifies it against the device key it stores. The Secure Keystore verifies it against the device public keys stored per unit at registration. PowerAuth Server must report exactly those keys for the activation, and when a user-signing key signs, the thumbprints sealed in the wrapped key must match them too.

The two models protect against replay differently. The German model uses PIN sessions and challenges. Here each signed request carries iat and a single-use jti, which the keystore remembers while iat is accepted.

The PIN is handled differently too:

  • German model: the WSCA verifies the PIN itself, through the PIN key of a PIN session.
  • Secure Keystore: the PIN or biometry gates the device private keys. PowerAuth’s vault releases them only after a vault unlock, which PowerAuth Server verifies and counts. The keystore never sees a PIN or a PowerAuth code.

Where the German Design Departs from the Standards

Topic German design Secure Keystore (follows the standards)
Refresh-token binding Bound by DPoP to a separate HSM key Bound to the WIA key
WIA at the token endpoint Not sent at the first PID issuance The WIA and its PoPs go to PAR and the token endpoint
Status in the key attestation None Every key attestation carries a status entry
Last updated on Nov 11, 2026 (21:37) Edit on Github Send Feedback

develop

Secure Keystore