Password storage architecture: how encryption is arranged in 1Password, Bitwarden, KeePass and browser managers

Depov

Moderator
Staff member
MODERATOR
ULTIMATE
SUPREME
PREMIUM
MEMBER
Joined
Feb 18, 2025
Messages
142
Reaction score
152
Deposit
0$
In 2022, LastPass servers compromised, and the attackers took out the encrypted store of users - in total. Passwords inside were encrypted on the client side, but the URL of the sites, records names and metadata lay in the open form. In the following months, the crypto community recorded theft of assets from those whose master passwords were weak enough for offline over-separation. This postmortem is not about the "bad password manager." It is about specific architectural solutions: what KDF, how many iterations, what exactly is encrypted and what is not. We will analyze the password storage architecture in four fundamentally different classes of managers and show why with the same marketing "AES-256" real resistance differs in order.
Selection criteria: why these four classes
Four architecturally different approaches are not four "best managers", but four different theories of storing secrets:
• KeePass/KeePassXC is a local file base, without cloud synchronization from the box. Open source code. Purely offline model. You decide for yourself where you lie .kdbx.
• Bitwarden is a cloud manager with zero-knowledge architecture and self-hosting option. Open source code. Cloud open-source model.
• 1Password is a cloud manager with a proprietary model Two-Secret Key Derivation (2SKD). Closed code, but public whitepaper and independent audits. Model with an additional secret of the device.
• Browser managers (Chrome, Firefox, Safari/iCloud Keychain) - built into the browser, integration with key OSchain. Security is tied to the OS account. And here the most interesting thing begins.
Behind the review frame: Dashlane, Keeper, NordPass - their architecture is not fundamentally different from Bitwarden/1Password (zero-knowledge + cloud), the differences are reduced to UX. LastPass is excluded for another reason: after the 2022 incident, its threat model has changed so much that the correct comparison requires a separate analysis.
KDF under the microscope: how the master password becomes the encryption key
Master-password - a string of arbitrary length. AES-256 requires a key of exactly 256 bits. Between them is Key Derivation Function - and it is here that the border between "hack in an hour on the GPU farm" and "break through the century" passes.
PBKDF2 - proven, but vulnerable to GPU-overruned
PBKDF2-HMAC-SHA256 - Standard from RFC 8018. The principle is simple: multiple applications of HMAC with unique salt. A critical parameter is the number of iterations.

After the incident with LastPass Bitwarden raised the default to 600 000 iterations on the client and added Argon2id support as an alternative. 1Password uses PBKDF2 with 650,000 iterations (according to the actual whitepaper), but in conjunction with Secret Key (128 bits of additional entropy) - and this radically changes the threat model. LastPass at the time of compromising, he defaulted 100 100 iterations for new accounts, and the old values could have been 5 000 or even 1 without forced migration. Think about it: one iteration.

PBKDF2 problem: It is perfectly parallel to GPU and ASIC. At stand with NVIDIA RTX 4090 hashcat in the finter mode, the PBKDF2-HMAC-SHA256 hashes with 600 000 iterations gives out about hundreds - low thousand attempts per second (depending on specific parameters of KDF). For an 8-symbolic password of lowercase Latin letters - too much for days or weeks. The Password Cracking Technique (T11100.002, Credential Access) - this is how the attackers work with stolen vault files.
Argon2id - memory as a protection factor
Argon2 - winner Password Hashing Competition 2015. Key difference from PBKDF2: in addition to computational complexity, requires a fixed amount of RAM. Argon2id is a hybrid, resistant to side-channel attacks, and to GPU-to-reflection.

KeePass 2.x uses Argon2d, KeePassXC (from version 2.6.0) - Argon2id as a default KDF for new KDBX 4.0 bases. Settings: iterations, memory (in MB), parallelism. Bitwarden added Argon2id as an option - default: 3 iterations, 64 MB of memory, 4 streams.

Why this is critical: GPU have high computing power, but limited nucleus memory. Argon2id with 64 MB makes a mass thug on the GPU cluster is economically inexpedient - each ticket thread requires the allocation of this volume. Roughly speaking, a farm of ten RTX 4090 does not rest in the CUDA core, but in VRAM.
Browser managers - KDF outside user control
Chrome stores passwords in SQLite-base Login Data, encrypting values through OS API: DPAPI on Windows, Keychain on macOS. There is no master password in the classical sense - the key is tied to the session of the user OS. Firefox uses NSS with optional Primary Password, but by default it is disabled. I mean, the default is nothing.

If the attacker received an active session of Windows (via RDP, physical access, malvar), DPAPI protection Chrome is disabled CryptUnprotectData without additional secrets. This is a direct vector for the equipment Credentials from Web Browsers (T1555.003, Credential Access) - one of the most popular techniques in the arsenal of styles (RedLine, Raccoon, Vidar). One line of code - and all passwords in the open form.
Hierarchy of keys: why architecture is more important than an algorithm
The same AES-256 protects data in completely different ways depending on how the key hierarchy is organized. The algorithm is a castle. The hierarchy of keys is how many doors and in what order.

KeePass uses a flat model: Composite Key (master-password + optional key file + binding to Windows account) through the KDF turns into a single key that encrypts the entire KDBX base (AES-256-CBC or ChaCha20). Change of master password - complete re-registration of the file. It is not possible to give a colleague access to one folder without opening the others. For SOC, this simplifies monitoring: file .kdbx does not leave the perimeter (if not manually synchronized), any contact with it by a process other than KeePass.exe/KeePassXC.exe- analt. Technique: Credentials In Files (T1552.001, Credential Access)

Bitwarden implements a two-level scheme. From the master password and email (like salt) through KDF is computed by Master Key. They decrypt the Symmetric Key - accidentally generated during registration, stored on the server in an encrypted form. Symmetric Key encrypts separate vault records. For auto-auditation of Master Key, Master Password Hash is calculated (an additional passage of PBKDF2 with 1 iteration), which is sent to the server where its bcrypt-hash is stored. Even when compromising the server base, the attacker receives a bcrypt-hash from a derivative - it's not the encryption key itself. When changing the master password, only Symmetric Key is converted, not all vault. Elegant.

1Password uses the Two-Secret Key Derivation (2SKD) – and this is the architecturally stronger than all the others in the server compromising scenario. The encryption key is calculated from the Master Password and Secret Key - a randomly generated 128-bit line that is created when registering and stored only on user devices. 1Password servers do not know this Secret Key. Even if the servers are compromised and the attacker received encrypted vaults, the search of the master password is useless without Secret Key. 128 bits of additional entropy make brute-force unrealistic. Reverse side: Loss of Secret Key = loss of data without the possibility of server recovery. 1Password recommends printing an Emergency Kit and stored in a physical safe. Paper in the safe as the last line of defense - in 2025 sounds ironic, but works.

Browser managers tie the key to the OS session. Chrome via DPAPI, Firefox via NSS. CVE-2019-11733 (CVSS 9.8, CWE-287 - Improper Authentication) showed a critical defect of Firefox: passwords were copied to the clipboard through the context menu without re-entering the master password if it was entered earlier in the same session (Firefox < 68.0.2). Direct vector for Clibboard Data (T1115, Collection)
Comparison of password managers encryption architecture
1782933923371.png

Threats and detection: what to monitor in SOC
For SOC-analyst, the password manager is not only an object of protection, but also the attack vector. MITRE ATT&CK allocates equipment Password Managers (T1555.005, Credential Access): Removing credentials from a manager on a compromised host.
Detection by managerial class
KeePass (.kdbx files): Referring to the files *.kdbx processes other than KeePass/KeePassXC. In EDR (CrowdStrike Falcon, Elastic 8.x+, SentinelOne) - FileRead-event event with an expansion filter. Launch keepass2john - the attacker extracts hash for offline over-turn (T1110.002) Copying .kdbx on removable carriers - T1552.001.

Bitwarden (self-hosted): Abnormal number of requests to /api/sync. Bitwarden Event Logs: Unprepared Authentication, Entry from New IPs. For 1Password Business - 1Password Events API with integration in SIEM.

Browsers: Appeal to Login Data (Chrome) or logins.json/key4.db (Firefox) non-standard processes - classic IOC stylers. Challenges CryptUnprotectData from atypical processes - for partial coverage, the DPAPI Activity audit (events 4692–4695 for operations with master key), but the regular audit does not record any call CryptUnprotectData; full coverage requires direct connection of the ETW provider Microsoft-Windows-Crypto-DPAPI A tool like SilketW. Kaeliging (T1056.001, Credential Access) when entering the master password - monitoring SetWindowsHookEx through the EDR.

Insider threat: A legitimate employee with access to organizational vault Bitwarden/1Password exports the base. Detection: logging of export/download events in Events API, correlation with atypical time (night hours, weekends) and volume of unloaded entries. An employee exporting 500 entries at 2 nights on Friday is not "forgot the Wi-Fi password."
YAML:
title: Suspicious Access to Password Manager Vault Files
logsource:
category: file_event
product: windows
detection:
selection:
TargetFilename|endswith:
- '.kdbx'
- 'Login Data'
- 'logins.json'
- 'key4.db'
filter:
Image|endswith:
- 'KeePass.exe'
- 'KeePassXC.exe'
- 'chrome.exe'
- 'firefox.exe'
condition: selection and not filter
level: high
 
Top Bottom