{"record":{"id":"9df1db28accd8a86","repo":"moonD4rk/HackBrowserData","slug":"dpapi-decrypt-w","errorCode":null,"errorMessage":"DPAPI decrypt: %w","messagePattern":"DPAPI decrypt: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"masterkey/retriever_windows.go","lineNumber":44,"sourceCode":"\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)\n\t}\n\n\tmasterKey, err := crypto.DecryptDPAPI(keyBytes[len(dpapiPrefix):])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"DPAPI decrypt: %w\", err)\n\t}\n\treturn masterKey, nil\n}\n\n// DefaultRetrievers wires the Windows tiers: DPAPI for v10, ABE for v20 (Chrome 127+, via reflective\n// injection). Both run — a profile upgraded from pre-v127 mixes v10+v20 and needs both (issue #578).\nfunc DefaultRetrievers() Retrievers {\n\treturn Retrievers{\n\t\tV10: &DPAPIRetriever{},\n\t\tV20: &ABERetriever{},\n\t}\n}\n","sourceCodeStart":26,"sourceCodeEnd":57,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/masterkey/retriever_windows.go#L26-L57","documentation":"This wraps a failure from crypto.DecryptDPAPI, which calls the Windows DPAPI CryptUnprotectData API on the bytes following the 'DPAPI' prefix. DPAPI only succeeds when the blob was protected under the same Windows user (and, for machine-scope, the same machine), so failure means the master key could not be decrypted in this context.","triggerScenarios":"DecryptDPAPI returned an error from CryptUnprotectData: running as a different Windows user than the one whose profile is being read; the Local State was copied from another machine; the DPAPI blob is corrupt; roaming-profile/credential-restore issues broke the master key.","commonSituations":"Security tool run via SSH, a service account, or an elevated process with a different logon session than the browser's; analyzing a copied-off profile on another machine; browser profile migrated between machines; corrupted Local State after a crash.","solutions":["Run the tool as the same Windows user account that owns the browser profile (impersonate or log in as that user).","Use machine-context DPAPI recovery options or the user's password via DPAPI backup-key recovery when off-box analysis is required.","Re-open the browser on the original machine/user so Chrome can regenerate a decryptable key (existing saved data re-encrypts on next use).","If corrupt-blob is suspected, replace the Local State with a fresh one from a healthy profile of the same user.","For Chrome 127+ v20 cookies, ensure the ABE retriever is used — DPAPI v10 keys will not decrypt v20 payloads."],"exampleFix":"// before: running as service account, DPAPI fails silently in context\nkey, err := retriever.RetrieveKey(hints)\n// after: verify same-user context before calling\nif cur, _ := user.Current(); cur.Username != profileOwner {\n\treturn nil, fmt.Errorf(\"must run as %s for DPAPI decrypt\", profileOwner)\n}\nkey, err := retriever.RetrieveKey(hints)","handlingStrategy":"try-catch","validationCode":"// Precondition checks possible before the call:\nif runtime.GOOS != \"windows\" { return errors.New(\"DPAPI requires Windows\") }\nif cur, _ := user.Current(); cur.Username != expectedOwner {\n\treturn fmt.Errorf(\"run as profile owner %s\", expectedOwner)\n}","typeGuard":null,"tryCatchPattern":"key, err := retriever.RetrieveKey(hints)\nif err != nil && strings.Contains(err.Error(), \"DPAPI decrypt\") {\n\t// impersonate profile owner or fall back to ABE retriever for v20\n}","preventionTips":["Run the tool as the same Windows user that owns the browser profile.","Don't analyze copied-off profiles off-box without DPAPI backup keys.","Keep browser and tool on the same machine for machine-scope blobs.","Handle Chrome 127+ v20 via the ABE path instead of DPAPI."],"tags":["dpapi","windows","crypto","permissions"],"backgroundTag":"decryption-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"}