Chrome Local State as a forensic artifact
2026-06-21 · 3 min
Local State gets opened, the os_crypt key gets copied, and the rest of
the file gets closed again. That is a missed read. The same JSON enumerates
every profile on the machine and the Google account behind each one, records
which profile was last active, and stamps the build. Decryption is one of the
things Local State does for you, not the only thing.
One file, at the User Data root
Local State is a single JSON file per browser install — it sits at the
root of the User Data directory, not inside a profile. There is one for
the whole installation, regardless of how many profiles exist. Edge is
identical:
%LOCALAPPDATA%\Google\Chrome\User Data\Local State
%LOCALAPPDATA%\Microsoft\Edge\User Data\Local State
Because it lives at the root, it is the natural index for a multi-profile machine: open it first and you know how many profiles you are dealing with before you touch any of them.
The encryption key (os_crypt)
The part everyone already reaches for:
{
"os_crypt": {
"encrypted_key": "RFBBUEkBAAAA0Iyd3wEV0RGM...",
"app_bound_encrypted_key": "QVBQQgEAAADQ..."
}
}
encrypted_keyis base64. Decode it and the first five bytes are the ASCII tagDPAPI; strip it and what remains is the AES key wrapped under the user's Windows credentials.app_bound_encrypted_key(Chrome 127+) carries theAPPBtag and holds the app-bound key used for v20 cookies and passwords.
This is the key that decrypts cookies, passwords and payment cards. It is wrapped, so you cannot read it out directly — the offline DPAPI chain covers the unwrap, and the cookie encryption post covers what the key then decrypts.
profile.info_cache — the profile roster
This is the part that gets skipped. profile.info_cache is a map of every
profile the browser knows about, keyed by directory name (Default,
Profile 1, …). Each entry includes:
{
"profile": {
"info_cache": {
"Profile 1": {
"name": "Work",
"user_name": "j.doe@contoso.com",
"gaia_id": "1078...4421",
"gaia_name": "Jane Doe",
"is_using_default_avatar": false,
"active_time": 1718900000.0
}
}
}
}
user_nameis the Google account email signed into that profile.gaia_id/gaia_nameare the account's stable Google identifier and display name.active_timeis roughly when the profile was last used.
So a single file ties each profile directory to a real person's email and account ID — before you have parsed a single cookie or history row. For the per-profile sign-in detail behind these fields, see Preferences and account forensics.
Last used and last active
Two sibling keys answer "which profile was actually in use":
profile.last_used— the directory name of the profile open most recently.profile.last_active_profiles— the set of profiles that were open in the last session.
On a machine with a personal and a work profile, this is what tells you which identity the user was operating under, not just which ones exist.
Browser metadata
Local State also stamps the install: the browser version, the
install date, and the active variations/experiments (feature flags
the build was running). Version and install date help you reason about which
encryption scheme to expect — pre-v80, v10, or v20 app-bound — and bound the
timeline of the install itself.
What the tool surfaces
The tool parses Local State and lays out both halves: it enumerates the
profiles with their emails, gaia_ids and last-active times, flags the
last-used profile, and surfaces the wrapped encrypted_key /
app_bound_encrypted_key so they feed straight into the decryption
workflow. One artifact answers "who, which profile, and what is the key" in
a single read. For where everything else lives once you know the profile
layout, see
where browsers store their artifacts.