{"record":{"id":"2949abdec1e34700","repo":"gchq/CyberChef","slug":"invalid-pkcs-7-padding","errorCode":null,"errorMessage":"Invalid PKCS#7 padding.","messagePattern":"Invalid PKCS#7 padding\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/SM4.mjs","lineNumber":323,"sourceCode":"                let iv2 = [...iv]; /* containing the IV + counter */\n                iv2[3] += (i >> 4);/* Using a 32 bit counter here. 64 Gb encrypts should be enough for everyone. */\n                iv2 = encryptBlockSM4(iv2, roundKey);\n                const block = bytesToInts(cipherText, i);\n                block[0] ^= iv2[0]; block[1] ^= iv2[1];\n                block[2] ^= iv2[2]; block[3] ^= iv2[3];\n                Array.prototype.push.apply(clearText, intsToBytes(block));\n            }\n            break;\n        default:\n            throw new OperationError(`Invalid block cipher mode: ${mode}`);\n    }\n    /* Check PKCS#7 padding */\n    if (mode === \"ECB\" || mode === \"CBC\") {\n        if (ignorePadding)\n            return clearText;\n        const padByte = clearText[clearText.length - 1];\n        if (padByte > 16)\n            throw new OperationError(\"Invalid PKCS#7 padding.\");\n        for (let i = 0; i < padByte; i++)\n            if (clearText[clearText.length -i - 1] !== padByte)\n                throw new OperationError(\"Invalid PKCS#7 padding.\");\n        return clearText.slice(0, clearText.length - padByte);\n    }\n    return clearText.slice(0, originalLength);\n}\n\n","sourceCodeStart":305,"sourceCodeEnd":332,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/SM4.mjs#L305-L332","documentation":"decryptSM4's PKCS#7 check at SM4.mjs:323. After decrypting an ECB/CBC buffer it reads the trailing byte as the pad length; if that value exceeds 16 (the SM4 block size) it cannot be a valid PKCS#7 pad and is rejected. This almost always means the plaintext is garbage — wrong key, wrong IV, or wrong mode.","triggerScenarios":"decryptSM4(cipherText, key, iv, mode='ECB'|'CBC', ignorePadding=false) where the last decrypted byte is greater than 16. Typical cause: decrypting with the wrong key/IV produces random plaintext whose final byte happens to be > 16.","commonSituations":"Key/IV mismatch between encrypt and decrypt; mode mismatch (encrypt was CTR but decrypt is CBC); ciphertext from a different cipher entirely; encrypt side did not apply PKCS#7 (e.g. used noPadding) but decrypt expects it.","solutions":["Confirm the key and IV are identical to those used for encryption.","Verify the encrypt mode matches the decrypt mode.","If the data was encrypted without PKCS#7 padding, decrypt with ignorePadding=true.","As a diagnostic, decrypt with ignorePadding=true and inspect the raw plaintext to see if it looks correct."],"exampleFix":"// before\nconst pt = decryptSM4(ct, wrongKey, iv, \"CBC\");\n// after\nconst pt = decryptSM4(ct, correctKey, iv, \"CBC\");","handlingStrategy":"validation","validationCode":"// After a trial decrypt with ignorePadding=true, sanity-check the trailing byte.\nfunction looksLikeValidPkcs7Pad(plain, blockSize = 16) {\n  if (plain.length === 0) return false;\n  const padByte = plain[plain.length - 1];\n  if (padByte < 1 || padByte > blockSize) 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 hasPlausiblePkcs7TrailingByte(plain, blockSize = 16) {\n  return plain.length > 0 && plain[plain.length - 1] >= 1 && plain[plain.length - 1] <= blockSize;\n}","tryCatchPattern":"import OperationError from \"../errors/OperationError.mjs\";\ntry {\n  const pt = decryptSM4(ct, key, iv, \"CBC\");\n} catch (e) {\n  if (e instanceof OperationError && /Invalid PKCS#7 padding/.test(e.message)) {\n    // retry with ignorePadding=true to inspect raw plaintext; treat as wrong-key/mode signal\n  } else throw e;\n}","preventionTips":["Keep key, IV, and mode identical between encrypt and decrypt.","If encrypt did not use PKCS#7, decrypt with ignorePadding=true and strip padding yourself.","Treat a padding error as an integrity signal — do not return partial plaintext."],"tags":["sm4","cipher","padding","pkcs7","decryption"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}