gchq/CyberChef · error · OperationError
Invalid PKCS#5 padding.
Error message
Invalid PKCS#5 padding.
What it means
Thrown by RC6.removePadding for PKCS5 when the trailing pad byte count is in range (1..blockSize) but at least one of the final N bytes does not equal N. PKCS#5 padding requires the last N bytes all to equal N; a mismatch means the ciphertext was wrong, the padding type was wrong, or the data is not PKCS5-padded.
Source
Thrown at src/core/lib/RC6.mjs:415
* @returns {number[]} - Unpadded message
*/
function removePadding(message, padding, blockSize) {
if (message.length === 0) return message;
switch (padding) {
case "NO":
case "ZERO":
case "RANDOM":
// These padding types cannot be reliably removed
return message;
case "PKCS5": {
const padByte = message[message.length - 1];
if (padByte > 0 && padByte <= blockSize) {
// Verify padding
for (let i = 0; i < padByte; i++) {
if (message[message.length - 1 - i] !== padByte) {
throw new OperationError("Invalid PKCS#5 padding.");
}
}
return message.slice(0, message.length - padByte);
}
throw new OperationError("Invalid PKCS#5 padding.");
}
case "BIT": {
// Find 0x80 byte working backwards, skipping zeros
for (let i = message.length - 1; i >= 0; i--) {
if (message[i] === 0x80) {
return message.slice(0, i);
} else if (message[i] !== 0) {
throw new OperationError("Invalid BIT padding.");
}
}
throw new OperationError("Invalid BIT padding.");
}View on GitHub (pinned to 4290ea7539)
Solutions
- Verify the key and IV match those used for encryption.
- Confirm the data was actually PKCS5-padded at encryption time.
- If unsure of padding, decrypt with 'NO' and inspect the tail bytes.
Example fix
// before: decrypt with PKCS5 though sender used BIT // after: match the sender's padding scheme const pt = decryptRC6(ct, key, iv, 'CBC', 'BIT');
Defensive patterns
Strategy: try-catch
Validate before calling
function isValidPkcs5Tail(message, blockSize) {
const n = message[message.length - 1];
if (n < 1 || n > blockSize) return false;
for (let i = 0; i < n; i++) if (message[message.length - 1 - i] !== n) return false;
return true;
} Type guard
function hasValidPkcs5Padding(message, blockSize) {
const n = message[message.length - 1];
return n >= 1 && n <= blockSize && message.slice(-n).every(b => b === n);
} Try / catch
try {
return decryptRC6(ct, key, iv, mode, 'PKCS5', rounds, w);
} catch (e) {
if (e instanceof OperationError && /Invalid PKCS#5 padding/.test(e.message)) {
// verify key/IV, or decrypt with 'NO' to inspect the tail bytes
return decryptRC6(ct, key, iv, mode, 'NO', rounds, w);
}
throw e;
} Prevention
- Confirm key/IV match those used to encrypt.
- Ensure the data was PKCS5-padded at the source.
- When in doubt, decrypt with 'NO' and inspect the final block.
When it happens
Trigger: Calling decryptRC6(...) with padding 'PKCS5' on ciphertext whose decrypted final block does not end in valid PKCS#5 bytes — wrong key, wrong IV, double-decryption, or the data was padded differently.
Common situations: Wrong key/IV producing random-looking plaintext; data was padded with ZERO/BIT but decrypted as PKCS5; ciphertext truncated/extended by a byte; CBC chain broken.
Related errors
- Invalid BIT padding.
- No padding requested but input is not a ${blockSize}-byte mu
- Unknown padding type: ${padding}
- Invalid PKCS#5 padding.
- No padding requested but input is not a ${blockSize}-byte mu
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/cc2b3fc4ebf2212e.
Report an issue: GitHub.