{"record":{"id":"ee83fe2b79eae714","repo":"gchq/CyberChef","slug":"iv-must-be-8-bytes-currently-iv-length-by","errorCode":null,"errorMessage":"IV must be 8 bytes (currently \" + iv.length + \" bytes)","messagePattern":"IV must be 8 bytes \\(currently \" \\+ iv\\.length \\+ \" bytes\\)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/AESKeyUnwrap.mjs","lineNumber":71,"sourceCode":"        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    run(input, args) {\n        const kek = Utils.convertToByteString(args[0].string, args[0].option),\n            iv = Utils.convertToByteString(args[1].string, args[1].option),\n            inputType = args[2],\n            outputType = args[3];\n\n        if (kek.length !== 16 && kek.length !== 24 && kek.length !== 32) {\n            throw new OperationError(\"KEK must be either 16, 24, or 32 bytes (currently \" + kek.length + \" bytes)\");\n        }\n        if (iv.length !== 8) {\n            throw new OperationError(\"IV must be 8 bytes (currently \" + iv.length + \" bytes)\");\n        }\n        const inputData = Utils.convertToByteString(input, inputType);\n        if (inputData.length % 8 !== 0 || inputData.length < 24) {\n            throw new OperationError(\"input must be 8n (n>=3) bytes (currently \" + inputData.length + \" bytes)\");\n        }\n\n        const cipher = forge.cipher.createCipher(\"AES-ECB\", kek);\n        cipher.start();\n        cipher.update(forge.util.createBuffer(\"\"));\n        cipher.finish();\n        const paddingBlock = cipher.output.getBytes();\n\n        const decipher = forge.cipher.createDecipher(\"AES-ECB\", kek);\n\n        let A = inputData.substring(0, 8);\n        const R = [];\n        for (let i = 8; i < inputData.length; i += 8) {\n            R.push(inputData.substring(i, i + 8));","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/AESKeyUnwrap.mjs#L53-L89","documentation":"RFC 3394 AES key wrap uses a fixed 8-byte IV (initial value / integrity check register), conventionally A6A6A6A6A6A6A6A6. AESKeyUnwrap requires args[1] to convert to exactly 8 bytes and throws otherwise. The IV length is independent of the KEK size.","triggerScenarios":"The IV argument converts to a byte string whose length is not 8. E.g. entering the default A6A6A6A6A6A6A6A6 as hex while format is UTF8 (16 bytes), or supplying a 16-byte value by mistake.","commonSituations":"IV format option (Hex/UTF8) does not match the supplied string; user confused the 8-byte wrap IV with a 16-byte AES-CBC IV; left IV blank.","solutions":["Provide the standard 8-byte IV A6A6A6A6A6A6A6A6 with the IV format set to Hex (→ 8 bytes).","If the wrap used a non-default IV, supply exactly that 8-byte value in the matching format.","Double-check the IV format option matches the string you pasted."],"exampleFix":"// before: IV \"A6A6A6A6A6A6A6A6\" format UTF8 → 16 bytes → throws\n// after: set IV format to \"Hex\" → 8 bytes","handlingStrategy":"validation","validationCode":"function validateWrapIv(ivBytes) {\n  if (ivBytes.length !== 8) {\n    throw new Error(`AES-KW IV must be 8 bytes, got ${ivBytes.length}`);\n  }\n}","typeGuard":"function isWrapIv(bytes) { return bytes instanceof Uint8Array && bytes.length === 8; }","tryCatchPattern":"try { aesKeyUnwrap(...); } catch (e) { if (/IV must be 8 bytes/.test(e.message)) {/* fix IV format */} else throw e; }","preventionTips":["Use the standard A6A6A6A6A6A6A6A6 IV in Hex format.","Do not confuse the 8-byte wrap IV with a 16-byte AES-CBC IV.","Verify the IV format option matches the pasted value."],"tags":["aes","key-wrap","iv","validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}