把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("明文数据已损坏"); } } }
来源:https://blog.csdn.net/qq_33017223/article/details/102752941