{"record":{"id":"351cf79d7676c51b","repo":"MyCATApache/Mycat-Server","slug":"failed-to-get-public-key","errorCode":null,"errorMessage":"Failed to get public key","messagePattern":"Failed to get public key","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/util/DecryptUtil.java","lineNumber":142,"sourceCode":"\t\tPublicKey publicKey = getPublicKey(publicKeyText);\n\n\t\treturn decrypt(publicKey, cipherText);\n\t}\n\n\tpublic static PublicKey getPublicKey(String publicKeyText) {\n\t\tif (publicKeyText == null || publicKeyText.length() == 0) {\n\t\t\tpublicKeyText = DecryptUtil.DEFAULT_PUBLIC_KEY_STRING;\n\t\t}\n\n\t\ttry {\n\t\t\tbyte[] publicKeyBytes = Base64.base64ToByteArray(publicKeyText);\n\t\t\tX509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(\n\t\t\t\t\tpublicKeyBytes);\n\n\t\t\tKeyFactory keyFactory = KeyFactory.getInstance(\"RSA\");\n\t\t\treturn keyFactory.generatePublic(x509KeySpec);\n\t\t} catch (Exception e) {\n\t\t\tthrow new IllegalArgumentException(\"Failed to get public key\", e);\n\t\t}\n\t}\n\n\n\tpublic static String decrypt(PublicKey publicKey, String cipherText)\n\t\t\tthrows Exception {\n\t\tCipher cipher = Cipher.getInstance(\"RSA\");\n\t\ttry {\n\t\t\tcipher.init(Cipher.DECRYPT_MODE, publicKey);\n\t\t} catch (InvalidKeyException e) {\n            // 因为 IBM JDK 不支持私钥加密, 公钥解密, 所以要反转公私钥\n            // 也就是说对于解密, 可以通过公钥的参数伪造一个私钥对象欺骗 IBM JDK\n            RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;\n            RSAPrivateKeySpec spec = new RSAPrivateKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent());\n            Key fakePrivateKey = KeyFactory.getInstance(\"RSA\").generatePrivate(spec);\n            cipher = Cipher.getInstance(\"RSA\"); //It is a stateful object. so we need to get new one.\n            cipher.init(Cipher.DECRYPT_MODE, fakePrivateKey);\n\t\t}","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/util/DecryptUtil.java#L124-L160","documentation":"DecryptUtil.getPublicKey() decodes a Base64 X.509-encoded RSA public key and asks the JCE KeyFactory to reconstruct it. If Base64 decoding or KeyFactory.generatePublic() fails for any reason, it rethrows as IllegalArgumentException('Failed to get public key') with the original cause attached.","triggerScenarios":"Passing a string that is not valid Base64 or not an X.509 SubjectPublicKeyInfo blob to getPublicKey(String); supplying an RSA public key exported in a different format (e.g. PKCS#1 'BEGIN RSA PUBLIC KEY' or OpenSSH format).","commonSituations":"Generating a keypair with openssl and pasting the public key directly without converting to X.509/SubjectPublicKeyInfo; whitespace or newlines corrupting the Base64; attempting to decrypt with a public key that was actually the private key field.","solutions":["Convert the key to X.509 SubjectPublicKeyInfo format: openssl rsa -pubin -in key.pub -pubout -outform DER | base64","Confirm the input is the public key (not private) and contains only valid Base64 characters with no headers/newlines","Inspect the wrapped cause (e.getCause()) — InvalidKeySpecException means wrong format, IOException/Base64 means corrupt input","Regenerate a fresh RSA keypair with Mycat's tooling if the source of the key is unknown"],"exampleFix":"// before\nopenssl rsa -in private.pem -pubout -out pub.pem // PKCS#1 or with PEM headers pasted directly\n// after\nopenssl rsa -in private.pem -pubout -outform DER | base64 -w0 // then pass this Base64 string","handlingStrategy":"try-catch","validationCode":"static boolean looksLikeX509Base64(String key){\n    if(key==null) return false;\n    String s = key.replaceAll(\"\\\\s\",\"\");\n    return s.length()%4==0 && s.matches(\"[A-Za-z0-9+/]+=*\") && s.length() > 100;\n}","typeGuard":null,"tryCatchPattern":"try { PublicKey pk = DecryptUtil.getPublicKey(b64); }\ncatch (IllegalArgumentException e) { throw new IllegalStateException(\"public key must be Base64 X.509 SubjectPublicKeyInfo; cause: \" + e.getCause(), e); }","preventionTips":["Export public keys as X.509/SubjectPublicKeyInfo (openssl -pubout), not PKCS#1","Strip PEM headers/footers and newlines before passing the Base64 body","Log e.getCause() to distinguish InvalidKeySpecException from Base64 corruption","Round-trip test: encode-then-decode the key once at startup"],"tags":["java","rsa","base64","cryptography"],"backgroundTag":"invalid-argument-format","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}