Skip to main content
A PasswordProtectedKey credential is a signing key whose private key is encrypted in your frontend and stored by DFNS as an opaque blob. DFNS never sees the password. During login and action signing, DFNS returns the encrypted key so the user can decrypt it locally with their password, sign, and discard the plaintext.
Password-protected keys let a user authenticate and sign with a password instead of a passkey. Use them when WebAuthn is unavailable or undesirable — for example, non-browser environments, or a credential the user needs across domains (passkeys are bound to a single domain). You own the full experience: you decide the encryption scheme, the password format, and the UX. The password never leaves the client.

How password-protected keys work

A PasswordProtectedKey carries an opaque encrypted blob that DFNS stores and returns to you. You implement the encryption; the user keeps the password.
  • On registration, you send the public key plus the encrypted private key as encryptedPrivateKey.
  • On login and action signing, DFNS returns the same blob back to you — as encryptedPrivateKey on each entry of allowCredentials.passwordProtectedKey. The user decrypts it with their password, signs the challenge, and never exposes the plaintext key.
DFNS stores the encrypted blob but never has the password. Only the user can decrypt and use the key.
Unlike a RecoveryKey, using a password-protected key does not invalidate the user’s other credentials — it is a normal first-factor signing credential.

Implementing password-protected keys

If implementing this in a browser without Node.js, use the @dfns/sdk-browser package for signing operations. If you must implement manually, see Base64Url encoding for correct encoding functions.
1

Generate a keypair and encrypt it with the user's password

When the user registers, generate a keypair and encrypt the private key with their password. This must happen on the client side — the password must never reach your server.
Frontend - Password-protected key generation
This AES-256-GCM + PBKDF2 scheme is one example. You choose the scheme — DFNS treats encryptedPrivateKey as an opaque string.
2

Register the password-protected key with DFNS

Send the public key and encryptedPrivateKey in the Complete User Registration call (or Complete End User Registration with Wallets). The password stays with the user.Which challenge to use. The credential signs the same challenge returned by the registration init endpoint (Create Registration Challenge, Create Delegated Registration Challenge, or Create Social Registration Challenge). All credentials in the same registration call share that one challenge.Build the clientData manually, since this is a key-style credential and not a Fido2 passkey. For registration, type is key.create:
Frontend - Build clientData for the PasswordProtectedKey
See Credentials Data for the exact clientData and attestationData formatting rules. Incorrect stringification causes Unable to verify signature errors.
Frontend - Include in registration request
To add a password-protected key after registration instead, use the Create Credential flow. The challenge then comes from Create Credential Challenge (or Create Credential Challenge With Code); the rest of the construction is identical.
3

Log the user in with the password-protected key

Login is a three-call flow, because Create Login Challenge is unauthenticated and returns the encrypted key. To stop anyone from fetching a user’s encrypted key to brute-force offline, DFNS first requires a one-time login code that proves the user controls their account.
1. Send a one-time login code
2. Create the login challenge with the code
3. Decrypt, sign, and complete login
Sign the clientData bytes, not the raw challenge. Encode both clientData and signature as base64url — standard base64 causes a 400 error.
4

Sign user actions

Non-read-only API calls require a user action signature. The flow mirrors login, but no login code is needed — the user is already authenticated, so Create User Action Challenge returns the encrypted key directly.
Sign a user action with a password-protected key

Security considerations

  • Password strength — Encourage strong passwords, and rate-limit login and signing to slow brute-force attempts against the encrypted blob.
  • Keep decryption on the client — Never send the password or the decrypted key to your server. Consider a Service Worker to perform crypto in a secure context.
  • Register a recovery path — A user who forgets their password loses that credential. Pair password-protected keys with a second credential or a recovery credential.

Credentials

Overview of credential kinds, including password-protected keys.

Credentials Data

How to build Client Data and Attestation Data objects.

Authentication flows

The full login flow, including the login-code step.

Registration flows

How credentials are registered.
Last modified on September 11, 2026