Overview
All vault data in Bitwarden is encrypted client-side using symmetric encryption before being sent to the server. This ensures end-to-end encryption where only the user can decrypt their data.
Encryption Process
String Encryption
The primary method for encrypting vault data:
Process:
- Generate random initialization vector (IV)
- Encrypt plaintext with AES-256-CBC
- Calculate HMAC-SHA256 over IV + ciphertext
- Return EncString with type, IV, ciphertext, and MAC
Decryption Process
AES-CBC-256 without HMAC (type 0) is deprecated and decryption is disabled. All vault data must use authenticated encryption (type 2 or 7).
Process:
- Verify HMAC over IV + ciphertext
- Decrypt ciphertext with AES-256-CBC using IV
- Return plaintext or throw on authentication failure
Byte Array Encryption
For encrypting binary data:
Cipher Encryption
Vault items (passwords, cards, identities, notes) are encrypted as “ciphers”:
Cipher Key Structure
Each cipher is encrypted with either:
- User Key: For items in the personal vault
- Organization Key: For items shared in an organization vault
Cipher Data Fields
Individual cipher fields are encrypted separately:
Each field is individually encrypted to enable fine-grained access control and to prevent information leakage through field lengths.
File Encryption
File attachments use a dedicated encryption method:
File Encryption Process
- Generate file key: Create a unique cipher key for the file
- Encrypt file data: Use AES-256-CBC + HMAC-SHA256
- Encrypt file key: Wrap the cipher key with user/org key
- Store both: Save encrypted file data and encrypted file key
File Decryption
Process:
- Unwrap cipher key using user/org key
- Verify HMAC on encrypted file data
- Decrypt file data using cipher key
- Return plaintext file bytes
Data Encryption Keys
Organization shared items use data encryption keys:
makeDataEncKey is deprecated for new code. Use cipher-specific keys or file encryption methods instead.
Key Wrapping
Symmetric keys are protected by wrapping them with other keys:
Symmetric Key Wrapping
Usage examples:
- User key wrapped with master key
- Cipher key wrapped with user key
- Organization key wrapped for sharing
Asymmetric Key Wrapping
Private keys are wrapped with symmetric keys:
Key Encapsulation
For sharing organization keys, asymmetric key encapsulation is used:
Process:
- Generate organization key (symmetric)
- Encrypt org key with each member’s RSA public key
- Store encrypted org keys per member
- Each member decrypts with their RSA private key
Decapsulation
Key encapsulation is “unsigned” - it doesn’t authenticate the sender. Only use for sharing within trusted organization contexts.
Encryption Security Properties
Authenticated Encryption
All modern encryption uses authenticated encryption:
- AES-256-CBC + HMAC-SHA256: Encrypt-then-MAC construction
- XChaCha20-Poly1305: Built-in authenticated encryption (AEAD)
Benefits:
- Prevents tampering with ciphertext
- Protects against padding oracle attacks
- Ensures data integrity and authenticity
Initialization Vectors
Every encryption operation uses a unique, random IV:
Never reuse IVs with the same key. IV reuse can completely break AES-CBC security, allowing attackers to recover plaintext.
Symmetric Key Structure
Symmetric keys contain both encryption and authentication components:
The encryption implementation delegates to the Bitwarden SDK for performance:
- SDK Integration: All cryptographic operations use optimized SDK implementations
- WebAssembly: SDK runs as WebAssembly for near-native performance
- Async Operations: Encryption is asynchronous to prevent UI blocking
Error Handling
Decryption failures should be treated as security-critical errors. Never ignore or suppress decryption exceptions.
Common decryption failure causes:
- Wrong decryption key
- Corrupted ciphertext
- MAC verification failure (tampering)
- Incompatible encryption type
Best Practices
For Developers
- Always use EncryptService: Don’t implement custom encryption
- Prefer high-level APIs: Use
encryptString over low-level primitives
- Validate encryption type: Check for authenticated encryption
- Handle errors properly: Don’t expose plaintext on decryption failure
Security Checklist
References
libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts - Encryption implementation
libs/common/src/key-management/crypto/abstractions/encrypt.service.ts - Encryption interface
libs/common/src/platform/models/domain/symmetric-crypto-key.ts - Key structure