把RSA公钥格式PKCS#1转换成PKCS#8 的坑在于 pom.xml导入的jar
/**
* rsa加密
* @author zcx
* @date 2019年10月18日
* */
public class GetRSA {
/**
* @param publicKeyPKCS8 为pkcs8格式的公钥
* */
public static String getRSA(String str,String publicKeyPKCS8) throws Exception {
byte[] cipherData= RSAEncrypt.encrypt(RSAEncrypt.loadPublicKeyByStr(publicKeyPKCS8),str.getBytes());
String cipher=Base64.encode(cipherData);
return cipher;
}
}
package com.dlc.modules.wxpaybank.util;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class RSAEncrypt {
private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
throws Exception {
try {
/**网上大部分都是这种写法,但是这个写法出来,会报 公钥非法,我怀疑,压根就没有把 PKCS#1转换成PKCS#8*/
/* byte[] buffer = Base64.decode(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
rsPublickey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
return (RSAPublicKey) publicKeyPKCS8;
*/
//把RSA公钥格式PKCS#1转换成PKCS#8
org.bouncycastle.asn1.pkcs.RSAPublicKey rsaPublicKey = org.bouncycastle.asn1.pkcs.RSAPublicKey.getInstance(
org.bouncycastle.util.encoders.Base64.decode(publicKeyStr));
java.security.spec.RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent());
java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("RSA");
java.security.PublicKey publicKeyPKCS8 = keyFactory.generatePublic(publicKeySpec);
return (RSAPublicKey)publicKeyPKCS8;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new Exception("无此算法");
} catch (InvalidKeySpecException e) {
e.printStackTrace();
throw new Exception("公钥非法");
} catch (NullPointerException e) {
e.printStackTrace();
throw new Exception("公钥数据为空");
}
}
/**
*
* 公钥加密过程
* @param publicKey
*
* @param plainTextData
* 明文数据
* @return
* @throws Exception
* 加密过程中的异常信息
*/
public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
throws Exception {
if (publicKey == null) {
throw new Exception("加密公钥为空, 请设置");
}
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(plainTextData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此加密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("加密公钥非法,请检查");
} catch (IllegalBlockSizeException e) {
throw new Exception("明文长度非法");
} catch (BadPaddingException e) {
throw new Exception("明文数据已损坏");
}
}
}