{"record":{"id":"bde9f9e52955cf5f","repo":"gchq/CyberChef","slug":"invalid-public-key-ensure-each-component-is-32-b","errorCode":null,"errorMessage":"Invalid Public Key - Ensure each component is 32 bytes in size and in hex","messagePattern":"Invalid Public Key - Ensure each component is 32 bytes in size and in hex","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/SM2Encrypt.mjs","lineNumber":66,"sourceCode":"                name: \"Curve\",\n                type: \"option\",\n                \"value\": [\"sm2p256v1\"],\n                \"defaultIndex\": 0\n            }\n        ];\n    }\n\n    /**\n     * @param {ArrayBuffer} input\n     * @param {Object[]} args\n     * @returns {byteArray}\n     */\n    run(input, args) {\n        const [publicKeyX, publicKeyY, outputFormat, curveName] = args;\n        this.outputFormat = outputFormat;\n\n        if (publicKeyX.length !== 64 || publicKeyY.length !== 64) {\n            throw new OperationError(\"Invalid Public Key - Ensure each component is 32 bytes in size and in hex\");\n        }\n\n        const sm2 = new SM2(curveName, outputFormat);\n        sm2.setPublicKey(publicKeyX, publicKeyY);\n\n        const result = sm2.encrypt(new Uint8Array(input));\n        return result;\n    }\n}\n\nexport default SM2Encrypt;\n","sourceCodeStart":48,"sourceCodeEnd":78,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/SM2Encrypt.mjs#L48-L78","documentation":"Thrown by SM2 Encrypt when either the public key X or Y component is not exactly 64 characters. SM2 public keys are an (X, Y) point on sm2p256v1, each coordinate being 256 bits = 32 bytes = 64 hex chars. The check runs before setPublicKey().","triggerScenarios":"Passing publicKeyX or publicKeyY with length != 64 — including the default placeholder 'DEADBEEF' (8 chars), keys with '0x' prefixes, uncompressed '04'||X||Y format (129 chars total), or whitespace-padded values.","commonSituations":"Leaving the default placeholders; pasting the full uncompressed public key (04-prefixed) into one field instead of splitting X and Y; copying only one coordinate; non-hex characters.","solutions":["Split the uncompressed public key (04 || X || Y) into two separate 64-char hex strings for X and Y.","Remove any '0x' prefix, '04' prefix, whitespace, and newlines.","Verify both publicKeyX.length === 64 and publicKeyY.length === 64 before calling."],"exampleFix":"// before\nsm2Encrypt.run(buf, [\"DEADBEEF\", \"DEADBEEF\", \"C1C3C2\", \"sm2p256v1\"])\n// after\nsm2Encrypt.run(buf, [\"<64 hex X>\", \"<64 hex Y>\", \"C1C3C2\", \"sm2p256v1\"])","handlingStrategy":"validation","validationCode":"function splitSm2PublicKey(full) {\n  const hex = String(full).trim().replace(/^04/, \"\").replace(/\\s+/g, \"\");\n  if (hex.length !== 128) throw new Error(\"Uncompressed key must be 04 + X + Y (130 hex chars)\");\n  return [hex.slice(0, 64), hex.slice(64, 128)];\n}\nfunction assertCoord(name, v) {\n  if (!/^[0-9a-fA-F]{64}$/.test(v)) throw new Error(`${name} must be 64 hex chars`);\n}","typeGuard":"function isValidSm2PublicKey(x, y) {\n  return /^[0-9a-fA-F]{64}$/.test(x) && /^[0-9a-fA-F]{64}$/.test(y);\n}","tryCatchPattern":null,"preventionTips":["Split an uncompressed (04-prefixed) key into separate X and Y hex strings.","Verify each coordinate is exactly 64 hex characters."],"tags":["crypto","sm2","key","operation","validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}