browserforensics
Back to all articles

Recover saved passwords across browsers

2026-06-21 · 4 min

A single host usually carries credentials in more than one browser, and each family stores them differently. This walkthrough takes you from raw profile files to a decrypted, exportable credential inventory across Chrome, Edge and Firefox — in one tab, with nothing uploaded.

What you're collecting

Two browser families, two storage models. Grab the right files for each one before you start.

BrowserFiles to collectSecret needed
Chrome / EdgeLogin Data (+ -wal), Local Stateos_crypt key
Firefoxlogins.json, key4.db (or key3.db)primary password (if set)

For Chromium, Login Data is the SQLite store; the encrypted passwords sit in logins.password_value. Local State carries the wrapped os_crypt key that decrypts them. For Firefox, logins.json holds the encrypted entries and key4.db holds the key NSS uses to unwrap them. One file without its partner is useless — collect them as pairs.

Chromium: recover the os_crypt key

Chromium passwords are v10/v20 AES-256-GCM blobs keyed by the profile's os_crypt key. That key is stored in Local State, but wrapped by the OS:

  • Windows — DPAPI, bound to the user account that created the profile.
  • Linux — the desktop keyring (GNOME Keyring / kwallet), or a hardcoded fallback key if no keyring is present.
  • macOS — the "Chrome Safe Storage" entry in the login Keychain.

Recover the os_crypt key from whichever source applies, then hand it to the tool alongside Login Data and Local State. The byte-level mechanics live in Chrome Login Data forensics and decrypt saved passwords and credit cards.

Firefox: the primary password

Firefox login values are 3DES-CBC, wrapped by a key in key4.db. By default there's no primary password, so the blank case is the common one. If the user set one, it's required to unwrap the key and there's no bypass.

The decryption is self-validating: NSS checks the entered password against a check blob before touching any login. A wrong password fails cleanly — it never produces garbage plaintext. If the tool returns credentials, they're real. The full NSS path is in decrypt Firefox passwords in your browser.

Run the decryption

In the tool, work one store at a time:

  1. Load the credential store. Chromium: drop Login Data and Local State. Firefox: drop logins.json and key4.db.
  2. Provide the secret. Chromium: the os_crypt key. Firefox: the primary password, or leave it blank.
  3. Decrypt. The work runs in the browser tab — Chromium via AES-256-GCM, Firefox via an in-browser NSS module. Nothing is uploaded.

Repeat for each browser on the host. The cleartext metadata — URLs, usernames, timestamps — is readable from the raw Login Data even before you supply a key, so you can scope the inventory first and decrypt only when the case needs the secret.

Review and export

Each row maps to one saved credential. Review:

  • origin_url — the site the credential belongs to.
  • username — almost always cleartext, often a real identity or email.
  • password — the decrypted secret.
  • date_last_used — separates a live credential from one saved and forgotten.

Sort by site to spot reuse, by username to link identities, by date_last_used to build a timeline. Then export the inventory as CSV or JSON to fold into your wider case notes.

What this is good for

  • Scope exposure after a compromise. Enumerate every credential a compromised host could have leaked.
  • Password-reuse audit. Sort the merged inventory and the same secret across multiple sites jumps out.
  • Account discovery. The URL and username columns map which sites the subject held accounts on — readable even when a password isn't recovered.

One honest limit

This covers browser-managed passwords only. Safari is the exception: its saved passwords live in the macOS Keychain, a separate OS-level store, not in a browser profile file — so they're out of scope here. Everything in this workflow runs client-side; no file or secret ever leaves the page.

Further reading