{"record":{"id":"ed0f844b3a4f61af","repo":"gchq/CyberChef","slug":"not-a-key-exchange-init","errorCode":null,"errorMessage":"Not a Key Exchange Init.","messagePattern":"Not a Key Exchange Init\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/HASSHClientFingerprint.mjs","lineNumber":76,"sourceCode":"     */\n    run(input, args) {\n        const [inputFormat, outputFormat] = args;\n\n        input = Utils.convertToByteArray(input, inputFormat);\n        const s = new Stream(new Uint8Array(input));\n\n        // Length\n        const length = s.readInt(4);\n        if (s.length !== length + 4)\n            throw new OperationError(\"Incorrect packet length.\");\n\n        // Padding length\n        const paddingLength = s.readInt(1);\n\n        // Message code\n        const messageCode = s.readInt(1);\n        if (messageCode !== 20)\n            throw new OperationError(\"Not a Key Exchange Init.\");\n\n        // Cookie\n        s.moveForwardsBy(16);\n\n        // KEX Algorithms\n        const kexAlgosLength = s.readInt(4);\n        const kexAlgos = s.readString(kexAlgosLength);\n\n        // Server Host Key Algorithms\n        const serverHostKeyAlgosLength = s.readInt(4);\n        s.moveForwardsBy(serverHostKeyAlgosLength);\n\n        // Encryption Algorithms Client to Server\n        const encAlgosC2SLength = s.readInt(4);\n        const encAlgosC2S = s.readString(encAlgosC2SLength);\n\n        // Encryption Algorithms Server to Client\n        const encAlgosS2CLength = s.readInt(4);","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/HASSHClientFingerprint.mjs#L58-L94","documentation":"Thrown by HASSH Client Fingerprint after the length/padding bytes are consumed. The SSH message code byte is read and compared against 20 (SSH_MSG_KEXINIT). Any other value means the record is not the key-exchange init message, so the HASSH algorithm string cannot be extracted.","triggerScenarios":"Feeding a valid SSH packet that is a different message type (NEWKEYS=21, KEX_DH_INIT=30, DISCONNECT=1, service request, etc.); feeding the server's KEX_INIT to the client fingerprint operation; feeding a later-stage packet.","commonSituations":"Captured the wrong handshake message; used server-direction bytes in the client operation; reordered a multi-packet capture; the connection failed before KEXINIT and only a DISCONNECT was sent.","solutions":["Confirm the packet is the client's SSH_MSG_KEXINIT (5th byte after the 4-byte length is decimal 20 / 0x14).","Use HASSH Server Fingerprint if the bytes came from the server direction.","Re-capture and pick the earliest KEX_INIT record in the TCP stream.","Check byte 5 (0-indexed offset 5) equals 0x14 before invoking."],"exampleFix":"// before: bytes are from a NEWKEYS (0x15) packet\nrun(newkeysHex, [\"Hex\", \"Hash\"]);\n// after: select the record whose 5th byte is 0x14\nconst kexInit = records.find(r => r[5] === 0x14);\nrun(kexInit, [\"Hex\", \"Hash\"]);","handlingStrategy":"validation","validationCode":"function isKexInit(bytes) {\n  // message code sits at offset 5 (4-byte length + 1 padding-length byte)\n  return bytes.length >= 6 && bytes[5] === 20;\n}","typeGuard":"function isClientKexInit(bytes) {\n  return isCompleteSshPacket(bytes) && bytes[5] === 20;\n}","tryCatchPattern":"try {\n  hash = hasshClient.run(hexInput, args);\n} catch (e) {\n  if (e instanceof OperationError && /Key Exchange Init/i.test(e.message)) {\n    // wrong message type - try the next record\n    hash = await nextRecord();\n  } else throw e;\n}","preventionTips":["Verify byte offset 5 equals 0x14 (decimal 20) before invoking.","Use the client-direction record for the client op.","Pick the earliest KEX_INIT in the handshake."],"tags":["ssh","hassh","fingerprinting","message-code","kex-init"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}