java RSA生成公钥和私钥
1.随机生成密钥对
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * 随机生成密钥对 * @throws NoSuchAlgorithmException */ public static void genKeyPair() throws NoSuchAlgorithmException { // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); // 初始化密钥对生成器,密钥大小为96-1024位 keyPairGen.initialize(1024,new SecureRandom()); // 生成一个密钥对,保存在keyPair中 KeyPair keyPair = keyPairGen.generateKeyPair(); // 得到私钥 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到公钥 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded())); // 得到私钥字符串 String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded()))); // 将公钥和私钥保存到Map //0表示公钥 keyMap.put(0,publicKeyString); //1表示私钥 keyMap.put(1,privateKeyString); }
2.RSA公钥加密
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * RSA公钥加密 * @param str 加密字符串 * @param publicKey 公钥 * @return 密文 * @throws Exception 加密过程中的异常信息 * */ public static String encrypt( String str, String publicKey ) throws Exception{ try { //base64编码的公钥 byte[] decoded = Base64.decodeBase64(publicKey); RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded)); //RSA加密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); byte[] strBytes = str.getBytes("UTF-8"); int inputLength = strBytes.length; System.out.println("加密字节数:" + inputLength); // 最大加密字节数,超出最大字节数需要分组加密 // 标识 int offSet = 0; byte[] resultBytes = {}; byte[] cache; while (inputLength - offSet > 0) { if (inputLength - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(strBytes, offSet, MAX_ENCRYPT_BLOCK); offSet += MAX_ENCRYPT_BLOCK; } else { cache = cipher.doFinal(strBytes, offSet, inputLength - offSet); offSet = inputLength; } resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length); System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length); } String outStr = Base64.encodeBase64String(resultBytes); return outStr; }catch (Exception e){ System.out.println("rsaEncrypt error:" + e.getMessage()); } return ""; }
3.RSA私钥解密
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * RSA私钥解密 * @param str 加密字符串 * @param privateKey 私钥 * @return 铭文 * @throws Exception 解密过程中的异常信息 */ public static String decrypt(String str, String privateKey) throws Exception{ //64位解码加密后的字符串 byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8")); //base64编码的私钥 byte[] decoded = Base64.decodeBase64(privateKey); RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)); //RSA解密 Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); ByteArrayOutputStream out = new ByteArrayOutputStream(); int inputLen = inputByte.length; System.out.println("解密字节数:" + inputLen); int offset = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offset > 0) { if (inputLen - offset > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(inputByte, offset, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(inputByte, offset, inputLen - offset); } out.write(cache, 0, cache.length); i++; offset = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); // 解密后的内容 String outStr = new String(decryptedData); return outStr; }
4.使用
private static final Map<Integer,String> keyMap=new HashMap<>(); /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //生成公钥和私钥 genKeyPair(); //加密字符串 String message = "sdaw"; System.out.println("随机生成的公钥为:" + keyMap.get(0)); System.out.println("随机生成的私钥为:" + keyMap.get(1)); String messageEn = encrypt(message,keyMap.get(0)); System.out.println(message + "\t加密后的字符串为:" + messageEn); String messageDe = decrypt(messageEn,keyMap.get(1)); System.out.println("还原后的字符串为:" + messageDe); }