moonD4rk/HackBrowserData · error

abe: encrypted key too short: %d bytes

Error message

abe: encrypted key too short: %d bytes

What it means

The base64-decoded app_bound_encrypted_key must be longer than the 'APPB' prefix so the prefix can be stripped. This error means the decoded blob was too short to contain even the prefix, i.e. it is not valid app-bound key material.

Source

Thrown at masterkey/abe_windows.go:89

	if localStatePath == "" {
		return nil, errNoABEKey
	}
	data, err := os.ReadFile(localStatePath)
	if err != nil {
		return nil, fmt.Errorf("abe: read Local State: %w", err)
	}

	raw := gjson.GetBytes(data, "os_crypt.app_bound_encrypted_key")
	if !raw.Exists() {
		return nil, errNoABEKey
	}

	decoded, err := base64.StdEncoding.DecodeString(raw.String())
	if err != nil {
		return nil, fmt.Errorf("abe: base64 decode: %w", err)
	}
	if len(decoded) <= len(appbPrefix) {
		return nil, fmt.Errorf("abe: encrypted key too short: %d bytes", len(decoded))
	}
	for i, b := range appbPrefix {
		if decoded[i] != b {
			return nil, fmt.Errorf("abe: unexpected prefix: got %q, want %q",
				decoded[:len(appbPrefix)], appbPrefix)
		}
	}
	return decoded[len(appbPrefix):], nil
}

View on GitHub (pinned to 0503d04d7a)

Solutions

  1. Check the raw app_bound_encrypted_key value in Local State — if it's empty or tiny, Chrome never stored the key and ABE cannot proceed.
  2. Launch Chrome once under the target user so it populates the app-bound key, then retry.
  3. Verify you decoded the correct JSON field and that base64 decoding succeeded on a full-length value.
  4. Fall back to a non-ABE decryption path or skip the browser when the key is absent.

Example fix

// before
raw := gjson.GetBytes(data, "os_crypt.app_bound_encrypted_key")
// after - detect empty/missing value before decoding
raw := gjson.GetBytes(data, "os_crypt.app_bound_encrypted_key")
if !raw.Exists() || len(raw.String()) == 0 {
	return nil, errNoABEKey
}
Defensive patterns

Strategy: validation

Validate before calling

decoded, err := base64.StdEncoding.DecodeString(rawKey)
if err != nil {
	return err
}
if len(decoded) <= len("APPB") {
	return fmt.Errorf("app_bound key too short (%d bytes); Chrome may not have stored a key", len(decoded))
}

Try / catch

key, err := RetrieveKey(exePath, localStatePath)
if err != nil {
	if strings.Contains(err.Error(), "too short") {
		log.Warnf("no app-bound key present in profile: %v; skipping", err)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: Calling RetrieveKey when the decoded value from Local State is empty or shorter than len(appbPrefix) bytes — e.g. the JSON field held an empty string, a very short non-key value, or a partially written/corrupted profile.

Common situations: Fresh/never-used Chrome profile where the key was never written; manually edited Local State; decoding the wrong field; profile corruption after a crash.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06). Data as JSON: /api/errors/5370e0f18f201449. Report an issue: GitHub.