peass-ng/PEASS-ng · error · System.Security.Cryptography.CryptographicException
Decryption failed due to MAC mismatch
Error message
Decryption failed due to MAC mismatch
What it means
During AES-GCM decryption the Bouncy Castle library raised InvalidCipherTextException, meaning the GCM authentication tag did not verify. The method wraps it in a CryptographicException with this message. The data is wrong, tampered with, or being decrypted with the incorrect key/nonce derivation — never proceed with the plaintext (which is not returned anyway).
Source
Thrown at winPEAS/winPEASexe/winPEAS/Info/CloudInfo/GWorkspaceInfo.cs:300
// Perform the decryption using Bouncy Castle
try
{
GcmBlockCipher gcm = new GcmBlockCipher(new Org.BouncyCastle.Crypto.Engines.AesEngine());
AeadParameters parameters = new AeadParameters(new KeyParameter(key), macLength * 8, nonce);
gcm.Init(true, parameters);
byte[] plaintext = new byte[gcm.GetOutputSize(actualCiphertext.Length)];
int len = gcm.ProcessBytes(actualCiphertext, 0, actualCiphertext.Length, plaintext, 0);
int len2 = gcm.DoFinal(plaintext, len);
string plaintextString = Encoding.ASCII.GetString(plaintext, 0, len+len2-mac.Length);
return plaintextString;
}
catch (InvalidCipherTextException ex)
{
throw new CryptographicException("Decryption failed due to MAC mismatch", ex);
}
}
private static bool IsPrefixMatch(byte[] ciphertext, byte[] versionPrefixBytes)
{
for (int i = 0; i < versionPrefixBytes.Length; i++)
{
if (ciphertext[i] != versionPrefixBytes[i])
return false;
}
return true;
}
private static byte[] PerformCryptography(byte[] data, ICryptoTransform cryptoTransform)
{
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream(ms, cryptoTransform, CryptoStreamMode.Write))View on GitHub (pinned to 53fb989abc)
Solutions
- Confirm the key retrieval chain: app-bound key from registry must first be decrypted with system-level DPAPI (as SYSTEM) before use as the AES key
- Verify nonce extraction: check that nonce is copied from exactly versionPrefixBytes.Length offset with the correct nonceLength (12 bytes for GCM)
- Re-read the full ciphertext blob; ensure no truncation or string encoding round-trips (always keep byte[]/REG_BINARY intact)
- Run the decryption in the correct security context (elevated/SYSTEM for Chromium app-bound keys)
- Log the inner InvalidCipherTextException for diagnosis, but treat MAC failure as authentication failure, not a retry case
Example fix
// before byte[] key = regReader.ReadRegistryValue(keyPath, valueName); // raw DPAPI blob used directly byte[] plain = DecryptWithAESGCM(cipher, key, "v20"); // after byte[] appBound = regReader.ReadRegistryKey(keyPath, valueName); byte[] key = SystemCrypto.ProtectedData.Unprotect(appBound, null, DataProtectionScope.LocalMachine); // decrypt with SYSTEM DPAPI byte[] plain = DecryptWithAESGCM(cipher, key, "v20");
Defensive patterns
Strategy: try-catch
Validate before calling
// MAC mismatch cannot be predicted; only ensure inputs are complete and correctly ordered
static bool PlausibleInput(byte[] ct, byte[] key, int nonceLen, int prefixLen) =>
ct != null && ct.Length > prefixLen + nonceLen + 16 && key != null && key.Length == 32; Try / catch
try { return DecryptWithAESGCM(ct, key, prefix); }
catch (CryptographicException ex)
{
log.Error($"AES-GCM auth failed (wrong key/nonce or tampered data): {ex.InnerException?.Message}");
return null; // never retry blindly; fix key derivation first
} Prevention
- Decrypt the app-bound key with SYSTEM-level DPAPI before using it as the AES key
- Verify nonce offset (after version prefix) and length (12 bytes) exactly match the format
- Keep REG_BINARY blobs intact — no truncation, no text encoding round-trips
- Run decryption in the same security context the key was encrypted for (elevated/SYSTEM)
- Treat every MAC failure as an authentication event worth logging, never a silent retry
When it happens
Trigger: Calling decryptedToken where the AES key (recovered from the app-bound key via system DPAPI) does not match the one used to encrypt, the nonce was mis-sliced from the ciphertext, or the ciphertext bytes were truncated/modified in transit.
Common situations: Running as a user whose DPAPI scope cannot decrypt the app-bound key (wrong user/SYSTEM context); Chrome updated and key format changed; copying only part of the registry REG_BINARY value; handling a token encrypted by a different machine/profile.
Related errors
- Invalid encryption version prefix.
- Keys > 32 are not supported
- Invalid digest length (required: 1 - 32)
- Salt length must be exactly 8 bytes
- Personalization length must be exactly 8 bytes
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/3cb2d93987b12fae.
Report an issue: GitHub.