moonD4rk/HackBrowserData · error
yandex: invalid protobuf signature on decrypted key
Error message
yandex: invalid protobuf signature on decrypted key
What it means
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.
Source
Thrown at crypto/yandex.go:21
import (
"bytes"
"errors"
)
// yandexSignature is the protobuf wire-format header (field1 varint=1, field2 len=32) on every wrapped key.
var yandexSignature = []byte{0x08, 0x01, 0x12, 0x20}
var localEncryptorPrefix = []byte("v10")
const (
yandexIntKeyBlobLen = 96 // 12B nonce + 68B ciphertext + 16B GCM tag
yandexDataKeyLen = 32
)
var (
errYandexMarkerNotFound = errors.New("yandex: v10 marker not found in local_encryptor_data")
errYandexBlobShort = errors.New("yandex: encrypted intermediate key truncated")
errYandexBadSignature = errors.New("yandex: invalid protobuf signature on decrypted key")
errYandexKeyTooShort = errors.New("yandex: decrypted intermediate key shorter than 32 bytes")
)
// DecryptYandexIntermediateKey unwraps the per-DB data key from meta.local_encryptor_data.
func DecryptYandexIntermediateKey(masterKey, blob []byte) ([]byte, error) {
idx := bytes.Index(blob, localEncryptorPrefix)
if idx < 0 {
return nil, errYandexMarkerNotFound
}
payload := blob[idx+len(localEncryptorPrefix):]
if len(payload) < yandexIntKeyBlobLen {
return nil, errYandexBlobShort
}
plaintext, err := AESGCMDecryptBlob(masterKey, payload[:yandexIntKeyBlobLen], nil)
if err != nil {
return nil, err
}View on GitHub (pinned to 0503d04d7a)
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.
Example fix
// before: master key copied from another profile's Local State key, err := DecryptYandexIntermediateKey(otherProfileMasterKey, blob) // after: resolve the master key for this specific profile masterKey, err := GetMasterKey(yandexLocalStatePath) key, err := DecryptYandexIntermediateKey(masterKey, blob)
Defensive patterns
Strategy: try-catch
Validate before calling
if len(masterKey) != 32 { return fmt.Errorf("master key must be 32 bytes, got %d", len(masterKey)) }
if len(blob) == 0 { return errors.New("empty yandex blob") } Try / catch
key, err := DecryptYandexIntermediateKey(masterKey, blob)
if errors.Is(err, errYandexBadSignature) {
// wrong master key or wrong blob region: re-extract and retry
return nil, fmt.Errorf("yandex key unwrap failed (check master key): %w", err)
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- yandex: decrypted intermediate key shorter than 32 bytes
- ciphertext too short
- ciphertext is not a multiple of the block size
- yandex: v10 marker not found in local_encryptor_data
- yandex: encrypted intermediate key truncated
AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06).
Data as JSON: /api/errors/7ef72cb541ac2b0d.
Report an issue: GitHub.