Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
at test.java.security.TestSignature.test(TestSignature.java:47)
at test.java.security.TestSignature.main(TestSignature.java:39)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
... 3 more
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:217)
at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
at test.java.security.TestSignature.test(TestSignature.java:47)
at test.java.security.TestSignature.main(TestSignature.java:39)
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351)
at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91)
at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75)
at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316)
at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213)
... 3 more
异常解释:
密钥解析错误,不是符合PKCS8规范的密钥
查api指出:InvalidKeySpecException
- 如果给定的密钥规范不适合此密钥工厂生成私钥。
错误点:
一开始传入的密钥既有问题,不是正确的rsa私钥,如果传入公钥错误也会报类似的InvalidKeySpecException
异常
修正后的代码
package test.java.security;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* 测试 Signature 对象
* Signature 用来为应用程序提供此数字签名算法功能。
* @author Administrator
*
*
支持的算法有:
NONEwithRSA
MD2withRSA/MD5withRSA
SHA1withRSA /SHA256withRSA/SHA384withRSA/SHA512withRSA
NONEwithDSA
SHA1withDSA
NONEwithECDSA/SHA1withECDSA/SHA256withECDSA/SHA384withECDSA/SHA512withECDSA/(ECDSA)
<digest>with<encryption> //任意的签名算法with 加密算法 ;例如 :<digest>with<encryption>and<mgf> :MD5withRSAandMGF1
*/
public class TestSignature {
//错误的rsa密钥
//public static String privateKey = "MIICXwIBAAKBgQC8I+R4gT2MihVxAFIJ+3UmKfFqMA6LKpLpKWsE87SKguAY2kTtaQoxwrwTWPB/36/uLKarHZYBN3CQ7Q9n3QP1hH9UiHyiKG4Iis97T6Qf5WgQ0B4WZSkdovsMnmQ21ux2Z9EBRDEgm5r6ZEiB8HGl5hDdp89NZSuOZvZC0ZJWsQIDAQABAoGBAJ/zy/x/tHpVs2D9KsJ93N1zb2IeNV8v9PLyWaA+KdJQ7oFyoINPeHFR5GB2jxHIdWSC5bg5URz7q2IriZt+Fiwgo+5REwoNI6r826hiIZ908WQZ8LKK+yDoU9ZuELDOzhIdrfiGOnJe39fr9zDdJRb1b2NNP3eysK0WQvX2NBw5AkEA9pBntSW8NeULcnsbVtv3DOuj+dE3rnJBxk8zoEYZ9OJphIoy1HdbMrjrJgZIOo0mVpN+DoJynbvE6WHmbo+GEwJBAMNXG2jp9Lao91vNauhoJOtWlrSzffHIlc561qi3x1WgE7nE1ZpgjRVcr1GYwXNoz+YPF16M8cdaLN3fSbyWGKsCQQCh/0DUSQW+101NG0tcJ0vLZmsnMOoHqLREijceP9DAD55KYc6BwCXgTpTZN9lu9txQl7mD6PtLXVpECHmw/IWXAkEAkKGSPd/bvNLmMyapHWLe0xDNjQXJHpgxsyvofAt2n8NiV42RyjfqvgJeHMBJm7XjGKfb2bnp2ny985k781H++QJBAIacHMT80RP+Q6Fs647+8DIppZ8PrAla2x55AXt4YDoOWWQbmBk0iiqLhuB0SuY+fAPln/zs79G7mHhny20uG58=";
public static String privateKey2 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBANCASiPfP0mt080jbcNsxCSXeCQa4OR7uIGvnKtjKqiWRPLG4EtYXAc24a/hUo6P19eDrVDGlon9/EMG8y+aQFJGjAcGWgYVx5VPHzBX/y7QNyO9MK7QhnXOnrCMbrEGfmPrpKD+r72G9pjant+Qqay9xbpWg0+BAdTUJ/TUMtmZAgMBAAECgYBSozY/Z4FW+31h5fPgK+DFu/8TGFAgXuTvCaJnz2Md9IkZTDejxT6cYWUr53toI5zhvz/XLw6FXNQ54KxMJq/s9PiZYUgq/PMrnyU4gBSTm5BmiWjdaGicVEZ1lofHjpkAchPNW/CzwxD8AeKI7QaObE+EkWbLAi6sa+nRdHKgrQJBAOwYLD2DncU15XCKS0RNzTrNohdBQcisOPHdtQO0CGZlxx3xjuU4WL6/EpdmbjTeYbOSDKCmY5vyVbYZdOWfEs8CQQDiFIwWpvW2WLxLVw3i2P55WmMMXuecwEzg++ae3Ht7nW0zNcWSsyvHh40sM8XqEzmWOzMY6JOePbkuVfWTc4cXAkBRzf5mQhiEoKwjVofF3v9hhKbJT/8vPR1uENgLtHHEqTdZFL3ihqeZUDNs6jz9bKCFy/E8KOsSueEg+6kZdwjZAkEAj2RW4fstd2VasDJb5ViaNqAEmJENOBej60L6KCJR07qqy0M8t+oaR2iLOtDvo6Jj8QxFQXQqRMCDVodAxjANKwJAL3KuaqA6kdy9RxdV3uP8nRXLY7C/1ZIK6U0pyZqKXEwpD+7Ar3hwwhPz9TeuoqjB/cCknZjw70BQFQ0/VUHW2g==";
public static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDQgEoj3z9JrdPNI23DbMQkl3gkGuDke7iBr5yrYyqolkTyxuBLWFwHNuGv4VKOj9fXg61QxpaJ/fxDBvMvmkBSRowHBloGFceVTx8wV/8u0DcjvTCu0IZ1zp6wjG6xBn5j66Sg/q+9hvaY2p7fkKmsvcW6VoNPgQHU1Cf01DLZmQIDAQAB+oXcINOiE3AsuZ4VJmwNZg9Y/7fY+OFRS2JAh5YMsrv2qyoGP+Z9ksre26NYR+Lt91B2lhdwJHLpQpziaANZm/ONb31fj/lwIDAQAB";
//private static String test = "test jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihgtest jiojiogeiojigouihg";
private static String test = "test huihiutg";
private static String algorithm = "NONEwithRSA";
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, SignatureException {
Signature sign = Signature.getInstance(algorithm);
String test2 = testEn(sign);
System.out.println(test2);
boolean testDn = testDn(test, sign, test2);
System.out.println(testDn);
}
//加密生成签名
public static String testEn(Signature sg) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException{
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey2));
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey generatePrivate = kf.generatePrivate(encodedKeySpec);
sg.initSign(generatePrivate);//初始化signature
sg.update(test.getBytes());//更新 signature
byte[] sign = sg.sign();//计算sign
String encodeToString = Base64.getEncoder().encodeToString(sign);
return encodeToString;
}
//验证签名
/**
*
* @param date 待签名数据
* @param sg
* @param signData 签名
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws SignatureException
* @throws InvalidKeyException
*/
public static boolean testDn(String date,Signature sg,String signData) throws NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, InvalidKeyException{
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatePublic = kf.generatePublic(encodedKeySpec);
sg.initVerify(generatePublic);
sg.update(date.getBytes());
boolean verify = sg.verify(Base64.getDecoder().decode(signData));
return verify;
}
}
注意:
由于用到了rsa做加密算法,因此数据大的时候还是要做分组加密,此处没做分组,如果加密数据超过117,解密数据超过128,也会报
javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes 异常