{"record":{"id":"21ca0fcd2db5deee","repo":"moonD4rk/HackBrowserData","slug":"read-local-state-w","errorCode":null,"errorMessage":"read Local State: %w","messagePattern":"read Local State: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"masterkey/retriever_windows.go","lineNumber":21,"sourceCode":"package masterkey\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/tidwall/gjson\"\n\n\t\"github.com/moond4rk/hackbrowserdata/crypto\"\n)\n\n// DPAPIRetriever unwraps Chrome's Local State os_crypt.encrypted_key via Windows DPAPI.\ntype DPAPIRetriever struct{}\n\nfunc (r *DPAPIRetriever) RetrieveKey(hints Hints) ([]byte, error) {\n\tdata, err := os.ReadFile(hints.LocalStatePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read Local State: %w\", err)\n\t}\n\n\tencryptedKey := gjson.GetBytes(data, \"os_crypt.encrypted_key\")\n\tif !encryptedKey.Exists() {\n\t\treturn nil, fmt.Errorf(\"os_crypt.encrypted_key not found in Local State\")\n\t}\n\n\tkeyBytes, err := base64.StdEncoding.DecodeString(encryptedKey.String())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"base64 decode encrypted_key: %w\", err)\n\t}\n\n\tconst dpapiPrefix = \"DPAPI\"\n\tif len(keyBytes) <= len(dpapiPrefix) {\n\t\treturn nil, fmt.Errorf(\"encrypted_key too short: %d bytes\", len(keyBytes))\n\t}\n\tif string(keyBytes[:len(dpapiPrefix)]) != dpapiPrefix {\n\t\treturn nil, fmt.Errorf(\"encrypted_key unexpected prefix: got %q, want %q\", keyBytes[:len(dpapiPrefix)], dpapiPrefix)","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/masterkey/retriever_windows.go#L3-L39","documentation":"On Windows, DPAPIRetriever reads Chrome's 'Local State' JSON file (in the profile's User Data dir) to obtain os_crypt.encrypted_key. os.ReadFile failed, so the path is wrong, the file is missing, or it cannot be opened — no V10 key can be unwrapped without it.","triggerScenarios":"RetrieveKey with hints.LocalStatePath pointing to a nonexistent/locked file: browser not installed at the expected location, wrong profile-dir hint, file held open exclusively, or running without read access to another user's profile.","commonSituations":"Custom Chrome install dir or non-default --user-data-dir; Chrome running and locking files (rare); the tool run as a different user without permissions on %LOCALAPPDATA%; typo'd path passed programmatically.","solutions":["Verify the path exists: the file lives at %LOCALAPPDATA%\\Google\\Chrome\\User Data\\Local State (adjust per browser)","Check hints.LocalStatePath is actually pointing to the 'User Data' root's Local State, not a profile subfolder (Default/…)","Ensure the process runs as the same user whose profile is being read, or as admin, with read access to the directory","Close Chrome or copy the file if it is locked, then retry"],"exampleFix":"// before\nretriever.RetrieveKey(masterkey.Hints{LocalStatePath: \"C:\\\\Program Files\\\\Google\\\\Chrome\\\\Local State\"})\n// after\nretriever.RetrieveKey(masterkey.Hints{LocalStatePath: filepath.Join(os.Getenv(\"LOCALAPPDATA\"), \"Google\", \"Chrome\", \"User Data\", \"Local State\")})","handlingStrategy":"validation","validationCode":"lsPath := filepath.Join(os.Getenv(\"LOCALAPPDATA\"), \"Google\", \"Chrome\", \"User Data\", \"Local State\")\nif fi, err := os.Stat(lsPath); err != nil || fi.IsDir() {\n    // Local State missing — fix hints.LocalStatePath or skip v10 tier\n}","typeGuard":null,"tryCatchPattern":"key, err := dpapiRetriever.RetrieveKey(hints)\nif err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && strings.Contains(err.Error(), \"read Local State\") {\n        log.Warnf(\"Local State unreadable at %s: %v\", hints.LocalStatePath, perr)\n    }\n}","preventionTips":["Build LocalStatePath from %LOCALAPPDATA% per browser instead of hardcoding paths","Point at the User Data root's 'Local State', never a Default/ subfolder file","Run as the profile's owning user (or elevated) when reading other profiles","Account for custom --user-data-dir installs and Chromium forks with different roots"],"tags":["windows","dpapi","file-not-found","local-state"],"backgroundTag":"file-read-failed","analyzedSha":"0503d04d7a8d0379d060268a74f1b149e5a0aad5","analyzedAt":"2026-09-06T13:38:28.707Z","contentChangedAt":"2026-09-06T13:38:28.707Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}