Skip to main content

Overview

The KeyService manages all cryptographic keys in Bitwarden, including user keys, organization keys, provider keys, and key pairs. It handles key generation, derivation, storage, and rotation.

Location

Interface

User Key Management

userKey$()

Returns an observable stream of the user’s encryption key.
Parameters:
  • userId - The user ID
Returns: Observable<UserKey | null> - Stream of user keys (null if user is locked/logged out) Example:

getUserKey()

Retrieves the user’s encryption key.
Parameters:
  • userId - Optional user ID
Returns: Promise<UserKey | null> - The user key or null
Deprecated. Use userKey$() with a required UserId instead.

setUserKey()

Sets the user key and stores any additional versions (auto, biometrics, pin).
Parameters:
  • key - The user key to set
  • userId - The user ID
Throws: Error when key or userId is null. Lock the account to clear a key.

hasUserKey()

Checks if a user key is available in memory.
Parameters:
  • userId - The user ID
Returns: Promise<boolean> - True if user key is available

clearStoredUserKey()

Clears the stored user key from storage.
Parameters:
  • userId - The user ID
Throws: Error when userId is null or undefined

Key Generation

makeUserKey()

Generates a new user key and encrypts it with the master key.
Parameters:
  • masterKey - The user’s master key
Returns: Promise<[UserKey, EncString]> - Tuple of new user key and encrypted version Throws: Error when master key is null or undefined
Deprecated. Interacting with the master key directly is prohibited. For new features, use SDK methods for user cryptography initialization or contact the KM team.

makeMasterKey()

Derives a master key from password using KDF.
Parameters:
  • password - The user’s master password
  • email - The user’s email address
  • kdfConfig - Key derivation function configuration
Returns: Promise<MasterKey> - Derived master key
Deprecated. Interacting with the master key directly is prohibited.

makeCipherKey()

Generates a new cipher encryption key.
Returns: Promise<CipherKey> - A new cipher key Example:

makeDataEncKey()

Generates a new data encryption key and wraps it with the provided key.
Parameters:
  • key - User key or organization key to wrap with
Returns: Promise<[SymmetricCryptoKey, EncString]> - New key and wrapped version
Deprecated. Do not use this for new code / new cryptographic designs.

makeSendKey()

Creates a Send encryption key from key material.
Parameters:
  • keyMaterial - Key material to derive from
Returns: Promise<SymmetricCryptoKey> - Send key

Asymmetric Key Operations

makeKeyPair()

Generates a new RSA key pair.
Parameters:
  • key - Symmetric key to wrap the private key with
Returns: Promise<[string, EncString]> - Tuple of [publicKey, wrappedPrivateKey] Throws: Error if the provided key is null
Deprecated. New use-cases should be done in the SDK. Contact the Key Management team.

makeOrgKey()

Creates a new organization key encrypted with the user’s public key.
Parameters:
  • userId - User ID for public key lookup
Returns: Promise<[EncString, T]> - Encrypted org/provider key and decrypted key Throws:
  • Error when userId is null or undefined
  • Error when no public key is found for the user

userPrivateKey$()

Returns an observable of the user’s decrypted private key.
Parameters:
  • userId - The user ID
Returns: Observable<UserPrivateKey | null> - Stream of private keys

userPublicKey$()

Returns an observable of the user’s public key.
Parameters:
  • userId - The user ID
Returns: Observable<Uint8Array | null> - Stream of public keys

userEncryptionKeyPair$()

Returns an observable of the user’s key pair (guaranteed to be consistent).
Parameters:
  • userId - The user ID
Returns: Observable<{privateKey, publicKey} | null> - Key pair or null

getFingerprint()

Generates a fingerprint phrase for a public key.
Parameters:
  • fingerprintMaterial - Material to include in fingerprint
  • publicKey - The public key
Returns: Promise<string[]> - Array of fingerprint words Throws: Error when publicKey is null or undefined

Master Key Operations

getOrDeriveMasterKey()

Retrieves or derives the master key from a password.
Parameters:
  • password - The master password
  • userId - The user ID
Returns: Promise<MasterKey> - The master key Throws:
  • Error when userId is null/undefined
  • Error when email or KDF config cannot be found
Deprecated. Use a high-level function from MasterPasswordService instead.

encryptUserKeyWithMasterKey()

Encrypts the user key with the master key.
Parameters:
  • masterKey - The master key
  • userKey - The user key to encrypt
Returns: Promise<[UserKey, EncString]> - User key and encrypted version Throws: Error when userKey or masterKey is null/undefined
Deprecated. Use a high-level function from MasterPasswordService instead.

hashMasterKey()

Creates a master password hash for authentication.
Parameters:
  • password - The master password
  • key - The master key
  • hashPurpose - Hash purpose (defaults to HashPurpose.ServerAuthorization)
Returns: Promise<string> - Password hash Hash Purposes:
Deprecated. Use a high-level function from MasterPasswordService instead.

Organization Key Management

setOrgKeys()

Stores encrypted organization keys.
Parameters:
  • orgs - Organization data
  • providerOrgs - Provider organization data
  • userId - The user ID

getOrgKey()

Retrieves an organization’s symmetric key.
Parameters:
  • orgId - The organization ID
Returns: Promise<OrgKey | null> - The organization key Throws: Error when not active user
Deprecated. Use the observable userOrgKeys$ and map to the desired OrgKey instead.

orgKeys$()

Returns an observable of all organization keys for a user.
Parameters:
  • userId - The user ID
Returns: Observable<Record<OrganizationId, OrgKey> | null> - Map of org IDs to keys Throws: Error if an invalid user ID is passed

Provider Key Management

setProviderKeys()

Stores provider keys for a user.
Parameters:
  • providers - Provider organization data
  • userId - The user ID

providerKeys$()

Returns an observable of provider keys.
Parameters:
  • userId - The user ID
Returns: Observable<Record<ProviderId, ProviderKey> | null> - Map of provider IDs to keys Throws: Error if an invalid user ID is passed

Cipher Decryption Keys

cipherDecryptionKeys$()

Returns all keys needed for decrypting ciphers.
Parameters:
  • userId - The user ID
  • legacySupport - Support legacy key format (default: false)
Returns: Observable<CipherDecryptionKeys | null> - Decryption keys Types:
Throws: Error if an invalid user ID is passed

Account Initialization

initAccount()

Initializes all necessary crypto keys for a new account.
Parameters:
  • userId - The user ID
Returns: Promise<{userKey, publicKey, privateKey}> - Newly created keys Throws:
  • Error if userId is null or undefined
  • Error if user already has a user key
Deprecated. New cryptography initialization should be done in the SDK. See PM-21771.

Key Validation

validateUserKey()

Validates that a user key is correct for a given user.
Parameters:
  • key - The key to validate
  • userId - The user ID
Returns: Promise<boolean> - True if key is valid

Cleanup

clearKeys()

Clears all of the user’s keys from storage.
Parameters:
  • userId - The user ID
Throws: Error when userId is null or undefined

Key Types

All key types are branded types built on top of SymmetricCryptoKey or Uint8Array:
Location: libs/common/src/types/key.ts

KDF Configuration

Key Derivation Function (KDF) configurations control how master keys are derived from passwords.

KdfConfig

Union type for KDF configurations:

PBKDF2KdfConfig

PBKDF2-SHA256 configuration:
Example:

Argon2KdfConfig

Argon2id configuration:
Example:

KdfType

Location: libs/key-management/src/models/kdf-config.ts

Usage Examples

Generating and Setting User Key

Accessing User Keys

Deriving Master Key

Creating Organization Key

Getting Cipher Decryption Keys

Generating Fingerprint

Security Considerations

  1. Master Key Deprecation: Direct interaction with master keys is deprecated. Use MasterPasswordService for high-level operations.
  2. Key Storage: User keys should be cleared from memory when the user locks their vault.
  3. KDF Configuration: Use appropriate KDF parameters:
    • PBKDF2: Minimum 600,000 iterations
    • Argon2id: Minimum 2 iterations, 16 MB memory, 1 parallelism
  4. Key Validation: Always validate keys before use with validateUserKey().
  5. Observable Cleanup: Subscribe to key observables carefully to avoid memory leaks.
  6. SDK Migration: New cryptographic features should use SDK methods instead of these low-level functions.
  7. Error Handling: Many methods throw errors. Always wrap in try-catch blocks.
  8. User Context: Most operations require a UserId. Never use keys from one user for another user’s data.