{"record":{"id":"981aaf119583127a","repo":"spring-projects/spring-security","slug":"ssh-key-prefix-not-found","errorCode":null,"errorMessage":"SSH key prefix not found","messagePattern":"SSH key prefix not found","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java","lineNumber":234,"sourceCode":"\t\t\twriteBigInteger(stream, key.getPublicExponent());\n\t\t\twriteBigInteger(stream, key.getModulus());\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new IllegalStateException(\"Cannot encode key\", ex);\n\t\t}\n\t\toutput.append(base64Encode(stream.toByteArray()));\n\t\toutput.append(\" \" + id);\n\t\treturn output.toString();\n\t}\n\n\tprivate static RSAPublicKey parseSSHPublicKey(String encKey) {\n\t\tByteArrayInputStream in = new ByteArrayInputStream(base64Decode(encKey));\n\n\t\tbyte[] prefix = new byte[11];\n\n\t\ttry {\n\t\t\tif (in.read(prefix) != 11 || !Arrays.equals(PREFIX, prefix)) {\n\t\t\t\tthrow new IllegalArgumentException(\"SSH key prefix not found\");\n\t\t\t}\n\n\t\t\tBigInteger e = new BigInteger(readBigInteger(in));\n\t\t\tBigInteger n = new BigInteger(readBigInteger(in));\n\n\t\t\treturn createPublicKey(n, e);\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new RuntimeException(ex);\n\t\t}\n\t}\n\n\tstatic RSAPublicKey createPublicKey(BigInteger n, BigInteger e) {\n\t\ttry {\n\t\t\treturn (RSAPublicKey) KeyFactory.getInstance(\"RSA\").generatePublic(new RSAPublicKeySpec(n, e));\n\t\t}\n\t\tcatch (Exception ex) {\n\t\t\tthrow new RuntimeException(ex);","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/encrypt/RsaKeyHelper.java#L216-L252","documentation":"parseSSHPublicKey decodes the base64 payload of an SSH public key and expects the first 11 bytes to equal the 'ssh-rsa ' PREFIX. If the stream is too short or the prefix differs, the data is not a valid SSH-RSA key blob and this IllegalArgumentException is thrown.","triggerScenarios":"extractPublicKey matched the ssh-key regex but the base64 part decodes to bytes that do not start with 'ssh-rsa ' — e.g. truncated key, wrong base64 payload pasted, or an ssh-ed25519 blob's base64 mistakenly paired with a different algorithm token.","commonSituations":"Manually copying only part of a key from authorized_keys, editors wrapping/truncating long key lines, or mixing algorithm token and body from different keys.","solutions":["Re-copy the complete key line including full base64 body from the original .pub file.","Validate with 'ssh-keygen -l -f keyfile' that the key is intact and RSA.","Ensure the algorithm token in the string matches the embedded blob (both 'ssh-rsa').","Regenerate the key if the file is corrupt: ssh-keygen -t rsa -b 2048."],"exampleFix":"// before\nString key = \"ssh-rsa AAAATrunc\";\nRSAPublicKey pk = helper.extractPublicKey(key);\n// after\nString key = \"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQ...full key...\";\nRSAPublicKey pk = helper.extractPublicKey(key);","handlingStrategy":"validation","validationCode":"boolean isValidSshRsaBlob(String key) {\n    String[] p = key.trim().split(\"\\\\s+\");\n    if (p.length < 2 || !p[0].equals(\"ssh-rsa\")) return false;\n    try {\n        byte[] blob = Base64.getDecoder().decode(p[1]);\n        return blob.length >= 11 && new String(blob, 0, 7, StandardCharsets.US_ASCII).equals(\"ssh-rsa\");\n    } catch (IllegalArgumentException e) { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n    RSAPublicKey pk = helper.extractPublicKey(key);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"prefix not found\")) {\n        throw new ConfigException(\"Key body is not a valid ssh-rsa blob; re-copy the full .pub line\");\n    }\n    throw e;\n}","preventionTips":["Always read the key from the original .pub file rather than hand-copying.","Disable editors/plugins that wrap or truncate long lines when handling keys.","Decode-and-check the blob prefix before calling the helper.","Reject keys whose algorithm token and blob disagree."],"tags":["ssh-key","rsa","base64","corrupt-key"],"backgroundTag":"invalid-argument-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}