TheAlgorithms/C-Sharp · error · ArgumentException

Padding block is corrupted

Error message

Padding block is corrupted

What it means

GetPaddingCount performs a constant-time validity check on the padding: the arithmetic mask paddingCheckFailed is non-zero when the computed padding start index is negative (padding count zero or inconsistent with the data), and throws ArgumentException. This signals a corrupted or forged padding block — usually wrong key, corrupted ciphertext, or malicious input.

Solutions

  1. Verify key/IV/mode parity between encrypt and decrypt sides
  2. Switch to authenticated encryption so corruption is detected before unpadding
  3. Catch ArgumentException around unpadding and return a generic 'decryption failed' to avoid padding-oracle leaks

Example fix

// before
var count = padding.GetPaddingCount(data);
// after
try { var count = padding.GetPaddingCount(data); }
catch (ArgumentException) { throw new CryptographicException("Decryption failed"); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (input == null || input.Length == 0 || input[^1] == 0)
    throw new CryptographicException("Input cannot have valid padding");

Try / catch

try { count = padding.GetPaddingCount(data); }
catch (ArgumentException) { throw new CryptographicException("Decryption failed"); }

Prevention

When it happens

Trigger: Input whose last byte is 0x00, or whose derived paddingStartIndex is negative; occurs during unpadding of wrongly decrypted or tampered data.

Common situations: Wrong decryption key/IV, bit-flipped ciphertext, or padding-oracle probing attempts against a non-authenticated cipher setup.

Related errors


AI-assisted analysis of TheAlgorithms/C-Sharp@96e2905cab (2026-09-13). Data as JSON: /api/errors/7c4e987aea074d6f. Report an issue: GitHub.

Appendix: source

Thrown at Algorithms/Crypto/Paddings/Iso10126D2Padding.cs:119

        var lastByte = input[^1];
        var paddingCount = lastByte & 0xFF;

        // Calculate the index where the padding starts.
        var paddingStartIndex = input.Length - paddingCount;
        var paddingCheckFailed = 0;

        // The paddingCheckFailed will be non-zero under the following circumstances:
        // 1. When paddingStartIndex is negative: This happens when paddingCount (the last byte of the input array) is
        // greater than the length of the input array. In other words, the padding count is claiming that there are more
        // padding bytes than there are bytes in the array, which is not a valid scenario.
        // 2. When paddingCount - 1 is negative: This happens when paddingCount is zero or less. Since paddingCount
        // represents the number of padding bytes and is derived from the last byte of the input array, it should always
        // be a positive number. If it's zero or less, it means that either there's no padding, or an invalid negative
        // padding count has shomehow encoded into the last byte of the input array.
        paddingCheckFailed = (paddingStartIndex | (paddingCount - 1)) >> 31;
        if (paddingCheckFailed != 0)
        {
            throw new ArgumentException("Padding block is corrupted");
        }

        return paddingCount;
    }
}

View on GitHub (pinned to 96e2905cab)