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

  1. 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
  2. Verify nonce extraction: check that nonce is copied from exactly versionPrefixBytes.Length offset with the correct nonceLength (12 bytes for GCM)
  3. Re-read the full ciphertext blob; ensure no truncation or string encoding round-trips (always keep byte[]/REG_BINARY intact)
  4. Run the decryption in the correct security context (elevated/SYSTEM for Chromium app-bound keys)
  5. 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

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


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/3cb2d93987b12fae. Report an issue: GitHub.