{"record":{"id":"7ef72cb541ac2b0d","repo":"moonD4rk/HackBrowserData","slug":"yandex-invalid-protobuf-signature-on-decrypted-ke","errorCode":null,"errorMessage":"yandex: invalid protobuf signature on decrypted key","messagePattern":"yandex: invalid protobuf signature on decrypted key","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crypto/yandex.go","lineNumber":21,"sourceCode":"import (\n\t\"bytes\"\n\t\"errors\"\n)\n\n// yandexSignature is the protobuf wire-format header (field1 varint=1, field2 len=32) on every wrapped key.\nvar yandexSignature = []byte{0x08, 0x01, 0x12, 0x20}\n\nvar localEncryptorPrefix = []byte(\"v10\")\n\nconst (\n\tyandexIntKeyBlobLen = 96 // 12B nonce + 68B ciphertext + 16B GCM tag\n\tyandexDataKeyLen    = 32\n)\n\nvar (\n\terrYandexMarkerNotFound = errors.New(\"yandex: v10 marker not found in local_encryptor_data\")\n\terrYandexBlobShort      = errors.New(\"yandex: encrypted intermediate key truncated\")\n\terrYandexBadSignature   = errors.New(\"yandex: invalid protobuf signature on decrypted key\")\n\terrYandexKeyTooShort    = errors.New(\"yandex: decrypted intermediate key shorter than 32 bytes\")\n)\n\n// DecryptYandexIntermediateKey unwraps the per-DB data key from meta.local_encryptor_data.\nfunc DecryptYandexIntermediateKey(masterKey, blob []byte) ([]byte, error) {\n\tidx := bytes.Index(blob, localEncryptorPrefix)\n\tif idx < 0 {\n\t\treturn nil, errYandexMarkerNotFound\n\t}\n\tpayload := blob[idx+len(localEncryptorPrefix):]\n\tif len(payload) < yandexIntKeyBlobLen {\n\t\treturn nil, errYandexBlobShort\n\t}\n\n\tplaintext, err := AESGCMDecryptBlob(masterKey, payload[:yandexIntKeyBlobLen], nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/crypto/yandex.go#L3-L39","documentation":"DecryptYandexIntermediateKey decrypts the intermediate key blob from Yandex's meta.local_encryptor_data with AES-GCM and expects the plaintext to start with a fixed protobuf signature prefix. When the decrypted plaintext does not begin with that signature, the blob is not the expected protobuf structure, so the function refuses to return a key. This guards against decrypting with the wrong master key or parsing garbage.","triggerScenarios":"Calling DecryptYandexIntermediateKey(masterKey, blob) where AES-GCM decryption of blob succeeds but the plaintext lacks the yandexSignature prefix — i.e. wrong master key, or the blob extracted from local_encryptor_data is not the protobuf-wrapped intermediate key (wrong offset / wrong bytes region).","commonSituations":"Extracting the blob at the wrong offset after the v10/localEncryptorPrefix marker, using a master key from a different browser profile, or a Yandex version change that alters the protobuf wrapping of the intermediate key.","solutions":["Re-extract the master key for the exact Yandex profile being decrypted (keys are profile-specific).","Verify the blob starts right after localEncryptorPrefix and contains the full protobuf body; re-locate the v10 marker with bytes.Index.","Update/confirm yandexSignature against the current Yandex Browser version's protobuf layout.","Check for profile corruption by re-copying the profile data and retrying."],"exampleFix":"// before: master key copied from another profile's Local State\nkey, err := DecryptYandexIntermediateKey(otherProfileMasterKey, blob)\n// after: resolve the master key for this specific profile\nmasterKey, err := GetMasterKey(yandexLocalStatePath)\nkey, err := DecryptYandexIntermediateKey(masterKey, blob)","handlingStrategy":"try-catch","validationCode":"if len(masterKey) != 32 { return fmt.Errorf(\"master key must be 32 bytes, got %d\", len(masterKey)) }\nif len(blob) == 0 { return errors.New(\"empty yandex blob\") }","typeGuard":null,"tryCatchPattern":"key, err := DecryptYandexIntermediateKey(masterKey, blob)\nif errors.Is(err, errYandexBadSignature) {\n    // wrong master key or wrong blob region: re-extract and retry\n    return nil, fmt.Errorf(\"yandex key unwrap failed (check master key): %w\", err)\n}","preventionTips":["Always pair each profile with its own master key.","Slice blobs relative to localEncryptorPrefix, never fixed offsets.","Log blob length and prefix bytes on failure for diagnosis."],"tags":["yandex","decryption","protobuf","crypto"],"backgroundTag":"protobuf-unmarshal-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"}