{"record":{"id":"bf19739d21ddca10","repo":"moonD4rk/HackBrowserData","slug":"yandex-encrypted-intermediate-key-truncated","errorCode":null,"errorMessage":"yandex: encrypted intermediate key truncated","messagePattern":"yandex: encrypted intermediate key truncated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crypto/yandex.go","lineNumber":20,"sourceCode":"\nimport (\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","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/crypto/yandex.go#L2-L38","documentation":"errYandexBlobShort is returned by DecryptYandexIntermediateKey when the bytes after the v10 marker are shorter than yandexIntKeyBlobLen (96 bytes: 12B nonce + 68B ciphertext + 16B GCM tag). A truncated payload cannot contain a complete encrypted intermediate key, so the function refuses to attempt GCM decryption.","triggerScenarios":"Calling DecryptYandexIntermediateKey where len(payload after marker) < 96 — typically a truncated DB value, a partially copied meta file, or the marker appearing near the end of a different structure by coincidence.","commonSituations":"Incompletely copied Yandex Browser profile (meta file truncated); reading the DB while the browser still writes it; slicing the payload at the wrong marker occurrence; SQLite reads from a locked/torn database.","solutions":["Re-copy the Yandex profile with the browser fully closed and re-run extraction.","Validate len(payload) >= 96 at the call site and skip short records with a warning.","Ensure the correct marker occurrence is used if multiple markers could appear in the blob.","Check for database locks/corruption (integrity check on the SQLite file) if many records are short."],"exampleFix":"// before\nkey, err := crypto.DecryptYandexIntermediateKey(masterKey, blob)\n// after\nidx := bytes.Index(blob, prefix)\nif idx < 0 || len(blob)-idx-len(prefix) < 96 {\n    return nil, fmt.Errorf(\"truncated record: %w\", errYandexBlobShort)\n}\nkey, err := crypto.DecryptYandexIntermediateKey(masterKey, blob)","handlingStrategy":"validation","validationCode":"const yandexIntKeyBlobLen = 96\nidx := bytes.Index(blob, markerPrefix)\nif idx >= 0 && len(blob)-idx-len(markerPrefix) < yandexIntKeyBlobLen {\n    return errors.New(\"yandex payload truncated\")\n}","typeGuard":"func yandexPayloadComplete(blob, prefix []byte, need int) bool {\n    i := bytes.Index(blob, prefix)\n    return i >= 0 && len(blob)-i-len(prefix) >= need\n}","tryCatchPattern":"key, err := crypto.DecryptYandexIntermediateKey(master, blob)\nif errors.Is(err, crypto.ErrYandexBlobShort) {\n    log.Warnf(\"yandex intermediate key truncated (%d bytes); skipping\", len(blob))\n    return nil\n}","preventionTips":["Copy profile files with the browser closed to avoid truncation.","Validate payload length (>=96 after marker) before decrypting.","Run an SQLite integrity check if many records appear short.","Re-slice from the correct marker occurrence if multiple exist."],"tags":["crypto","yandex","truncation","validation"],"backgroundTag":"payload-too-large","analyzedSha":"0503d04d7a8d0379d060268a74f1b149e5a0aad5","analyzedAt":"2026-09-06T13:38:28.707Z","contentChangedAt":"2026-09-06T13:38:28.707Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}