Java读取第三方RSA公钥遇algid parse error问题的解决
无法读取ssh-keygen生成的RSA公钥问题解决
问题背景
在Java中读取用于JWS事件签名的RSA公私钥时,私钥加载正常,但公钥读取失败。注意:密钥由第三方生成,无法修改其生成命令。
密钥生成命令
第三方使用以下命令生成密钥:
ssh-keygen -t rsa -P "" -b 4096 -m PEM -f jwtRS256.key ssh-keygen -e -m PEM -f jwtRS256.key > jwtRS256.key.pub
正常运行的私钥加载代码
java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider() ); String privateKeyPEM = Files.readString(Path.of("jwtRS256.key"), Charset.defaultCharset()); String privateKey = privateKeyPEM .replace("-----BEGIN RSA PRIVATE KEY-----", "") .replaceAll(System.lineSeparator(), "") .replace("-----END RSA PRIVATE KEY-----", ""); byte[] decodedPrivateKey = Base64.decodeBase64(privateKey); KeyFactory keyFactoryPrivate = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec keySpecPrivate = new PKCS8EncodedKeySpec(decodedPrivateKey); RSAPrivateKey privateKeyRSA = (RSAPrivateKey) keyFactoryPrivate.generatePrivate(keySpecPrivate);
公钥加载失败的代码及报错
尝试用以下代码加载公钥:
String publicKeyPEM = Files.readString(Path.of("jwtRS256.key.pub"), Charset.defaultCharset()); String publicKey = publicKeyPEM .replace("-----BEGIN RSA PUBLIC KEY-----", "") .replaceAll(System.lineSeparator(), "") .replace("-----END RSA PUBLIC KEY-----", ""); byte[] decodedPublicKey = Base64.decodeBase64(publicKey); KeyFactory keyFactoryPublic = KeyFactory.getInstance("RSA"); X509EncodedKeySpec keySpecPublic = new X509EncodedKeySpec(decodedPublicKey); PublicKey finalKeyPublic = keyFactoryPublic.generatePublic(keySpecPublic);
抛出错误:
Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:241) at java.base/java.security.KeyFactory.generatePublic(KeyFactory.java:351) at Main.jwstest(Main.java:65) at Main.main(Main.java:73) Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence at java.base/sun.security.x509.X509Key.decode(X509Key.java:397) at java.base/sun.security.x509.X509Key.decode(X509Key.java:402) at java.base/sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:151) at java.base/sun.security.rsa.RSAPublicKeyImpl.newKey(RSAPublicKeyImpl.java:78) at java.base/sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:327) at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:237) ... 3 more
尝试使用Bouncy Castle的PEMReader仍出现相同错误。
解决方法
使用Bouncy Castle的PEMParser和PublicKeyFactory处理公钥,最终可正常读取的代码如下:
PEMParser pemParser = new PEMParser(new FileReader("jwtRS256.key.pub")); Object object = pemParser.readObject(); SubjectPublicKeyInfo subjectPublicKeyInfo = (SubjectPublicKeyInfo) object; RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(subjectPublicKeyInfo); RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent()); KeyFactory kf = KeyFactory.getInstance("RSA", new BouncyCastleProvider()); PublicKey finalKeyPublic = kf.generatePublic(rsaSpec);
所需依赖
需在pom.xml中添加以下Bouncy Castle相关依赖:
<dependency> <groupId>org.bitbucket.b_c</groupId> <artifactId>jose4j</artifactId> <version>0.9.2</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> </dependency>
内容的提问来源于stack exchange,提问作者Chinmay Chandak
相关产品推荐
相关产品推荐

