gchq/CyberChef · error · OperationError
Invalid BIT padding.
Error message
Invalid BIT padding.
What it means
removePadding BIT (ISO 7816-4) branch walks backwards from the end expecting zero bytes followed by a single 0x80 terminator. If a non-zero, non-0x80 byte is encountered first, the padding is not a valid BIT sequence and decryption is rejected. Symptom of a wrong key or corrupted tail.
Source
Thrown at src/core/lib/Present.mjs:309
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.");
}
default:
throw new OperationError(`Unknown padding type: ${padding}`);
}
}
/**
* Encrypt using PRESENT cipher with specified block mode
*
* @param {number[]} message - Plaintext as byte array
* @param {number[]} key - Key (10 bytes for 80-bit or 16 bytes for 128-bit)
* @param {number[]} iv - IV (8 bytes, not used for ECB)
* @param {string} mode - Block cipher mode ("ECB" or "CBC")
* @param {string} padding - Padding type ("NO", "PKCS5", "ZERO", "RANDOM", "BIT")View on GitHub (pinned to 4290ea7539)
Solutions
- Verify the key matches the encrypting side exactly.
- Confirm BIT padding was used to encrypt; if not, pass the matching padding type.
- Decrypt with padding='NO' and inspect the tail bytes for a 0x80 marker.
- Check the IV and ciphertext integrity in CBC mode.
Example fix
// before const pt = decryptPRESENT(ct, key, iv, 'CBC', 'BIT'); // tail has stray byte -> error // after const raw = decryptPRESENT(ct, key, iv, 'CBC', 'NO'); console.log(raw.slice(-8)); // look for 0x80 terminator // if no 0x80 present, try the actual scheme: const pt = decryptPRESENT(ct, key, iv, 'CBC', 'PKCS5');
Defensive patterns
Strategy: try-catch
Validate before calling
function hasValidBITPadding(bytes) {
for (let i = bytes.length - 1; i >= 0; i--) {
if (bytes[i] === 0x80) return true;
if (bytes[i] !== 0) return false;
}
return false;
}
const raw = decryptPRESENT(ct, key, iv, mode, 'NO');
if (!hasValidBITPadding(raw)) throw new Error('Wrong key or non-BIT-padded source'); Try / catch
try {
return decryptPRESENT(ct, key, iv, mode, 'BIT');
} catch (e) {
if (!/BIT padding/.test(e.message)) throw e;
const raw = decryptPRESENT(ct, key, iv, mode, 'NO');
throw new Error('No valid BIT padding found; key is probably wrong or scheme is not BIT');
} Prevention
- Confirm the encrypting party used BIT (ISO 7816-4) padding.
- Verify the key and IV are correct.
- Use PKCS5 instead if you control both ends - it has clearer failure modes.
- Inspect the raw tail bytes when decryption fails to choose the correct padding scheme.
When it happens
Trigger: Calling decryptPRESENT(..., 'BIT') where the decrypted tail contains arbitrary non-zero bytes before any 0x80 marker. Typical with wrong key/IV, or when the data was not BIT-padded.
Common situations: Wrong key producing random plaintext; BIT padding not actually used on the encrypt side (e.g. PKCS5 was); corrupted final ciphertext block; mismatched IV in CBC mode.
Related errors
- Invalid PKCS#5 padding.
- No padding requested but input is not a ${blockSize}-byte mu
- Unknown padding type: ${padding}
- Invalid block cipher mode: ${mode}
- Invalid ciphertext length: ${cipherText.length} bytes. Must
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/a2c50b0ec0bf4323.
Report an issue: GitHub.