{"record":{"id":"28328d73fe27416b","repo":"gchq/CyberChef","slug":"invalid-pkcs-5-padding-28328d","errorCode":null,"errorMessage":"Invalid PKCS#5 padding.","messagePattern":"Invalid PKCS#5 padding\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/TEA.mjs","lineNumber":239,"sourceCode":" * @param {number[]} message\n * @param {string} padding\n * @returns {number[]}\n */\nfunction removePadding(message, padding) {\n    if (message.length === 0) return message;\n\n    switch (padding) {\n        case \"NO\":\n        case \"ZERO\":\n        case \"RANDOM\":\n            return message;\n\n        case \"PKCS5\": {\n            const padByte = message[message.length - 1];\n            if (padByte > 0 && padByte <= BLOCK_SIZE) {\n                for (let i = 0; i < padByte; i++) {\n                    if (message[message.length - 1 - i] !== padByte) {\n                        throw new OperationError(\"Invalid PKCS#5 padding.\");\n                    }\n                }\n                return message.slice(0, message.length - padByte);\n            }\n            throw new OperationError(\"Invalid PKCS#5 padding.\");\n        }\n\n        case \"BIT\": {\n            for (let i = message.length - 1; i >= 0; i--) {\n                if (message[i] === 0x80) return message.slice(0, i);\n                if (message[i] !== 0) throw new OperationError(\"Invalid BIT padding.\");\n            }\n            throw new OperationError(\"Invalid BIT padding.\");\n        }\n\n        default:\n            throw new OperationError(`Unknown padding type: ${padding}`);\n    }","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/TEA.mjs#L221-L257","documentation":"TEA's removePadding PKCS#5 inner-loop check at TEA.mjs:239. After the trailing byte passes the range check (1..BLOCK_SIZE), the code verifies each of the trailing padByte bytes equals padByte; any mismatch means the pad is malformed.","triggerScenarios":"Decryption with padding='PKCS5' where the trailing byte is in range [1..8] but the preceding (padByte-1) bytes do not all equal padByte. Causes: wrong key producing plaintext whose final bytes look like a plausible but inconsistent pad; partial corruption of the last block; encryptor used a different padding scheme (ZERO/BIT) but decryptor expects PKCS5.","commonSituations":"Key/IV mismatch where the random tail happens to start with a byte in 1..8; encrypt/decrypt padding scheme mismatch; bit-flip in the last ciphertext block.","solutions":["Verify key, IV, and mode match the encrypt side.","Confirm the encrypt-time padding was 'PKCS5'; if it was NO/ZERO/RANDOM/BIT, decrypt with that matching value.","As a diagnostic, decrypt with padding='NO' and inspect the raw tail bytes."],"exampleFix":"// before\nconst pt = decryptWithBlockMode(ct, key, iv, \"CBC\", \"PKCS5\");\n// after: data was ZERO-padded\nconst pt = decryptWithBlockMode(ct, key, iv, \"CBC\", \"ZERO\");","handlingStrategy":"validation","validationCode":"const TEA_BLOCK_SIZE = 8;\nfunction looksLikeValidPkcs5Pad(plain) {\n  if (plain.length === 0) return false;\n  const padByte = plain[plain.length - 1];\n  if (padByte < 1 || padByte > TEA_BLOCK_SIZE) return false;\n  for (let i = 0; i < padByte; i++)\n    if (plain[plain.length - 1 - i] !== padByte) return false;\n  return true;\n}","typeGuard":"function isConsistentPkcs5Pad(plain, blockSize = 8) {\n  const padByte = plain.length ? plain[plain.length - 1] : 0;\n  if (padByte < 1 || padByte > blockSize) return false;\n  return plain.slice(plain.length - padByte).every(b => b === padByte);\n}","tryCatchPattern":"import OperationError from \"../errors/OperationError.mjs\";\ntry {\n  const pt = decryptWithBlockMode(ct, key, iv, mode, \"PKCS5\");\n} catch (e) {\n  if (e instanceof OperationError && /Invalid PKCS#5 padding/.test(e.message)) {\n    // wrong key/IV or padding-scheme mismatch; do not return partial plaintext\n  } else throw e;\n}","preventionTips":["Decrypt with the same padding literal used to encrypt.","Treat PKCS#5 errors as a wrong-key/padding-mismatch signal.","Round-trip encrypt+decrypt in tests for every key/mode combination."],"tags":["tea","xtea","cipher","padding","pkcs5","decryption"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}