问题描述:
在使用Java原生API进行RSA私钥加载的时候,报错如下:
java.security.InvalidKeyException: IOException : algid parse error, not a sequence
原因分析:
通常JAVA中使用的RSA私钥格式必须为PKCS8格式,而我使用的私钥是PKCS1格式。
解决方案一,格式转换:
1,使用openssl进行格式转换,嫌麻烦我没有采用。
2,使用BouncyCastle 提供的api进行转换,详见这位老哥的博客,地址
3,使用在线工具转换(推荐),点击进入
解决方案二,使用BouncyCastle
1,如果是使用Gladle构建,那么添加BouncyCastle的依赖。
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.65'
注意,版本不要太高了,高版本需要jdk11或者更高版本jdk的支持。
2,下载jar包进行第三方库的使用,下载页面
3,可以使用BouncyCastle提供的API进行PKCS1格式私钥的加载
//私钥解密
public static byte[] privateDecryptByBouncyCastle(byte[] content, byte[] privateKeyBytes){
try {
RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(privateKeyBytes));
RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
KeyFactory keyFactory= KeyFactory.getInstance("RSA");
PrivateKey priKey= keyFactory.generatePrivate(rsaPrivKeySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, priKey);
return cipher.doFinal(content);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
4,也可以仍然使用JDK原生API,只需要在加载之前提前设置下Provider
Security.addProvider(BouncyCastleProvider())
附上原生JDK的私钥解密代码,也就是本篇文章一开始报错的方法。
//私钥解密
public static byte[] privateDecrypt(byte[] content, byte[] privateKeyBytes){
try {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(content);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
呜谢
1,与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence
2,RSA加密异常:java.security.InvalidKeyException: IOException : algid parse error, not a sequence,处理方法