|
|
@@ -0,0 +1,222 @@
|
|
|
+package com.pine.common.utils;
|
|
|
+
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
+import org.springframework.util.Base64Utils;
|
|
|
+
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.security.*;
|
|
|
+import java.security.interfaces.RSAPublicKey;
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
+import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
+import java.util.HashMap;
|
|
|
+
|
|
|
+import javax.crypto.BadPaddingException;
|
|
|
+import javax.crypto.Cipher;
|
|
|
+import javax.crypto.IllegalBlockSizeException;
|
|
|
+import javax.crypto.NoSuchPaddingException;
|
|
|
+
|
|
|
+public class RSAUtils {
|
|
|
+
|
|
|
+ private final static int MAX_DECRYPT_BLOCK = 128; //RSA最大解密密文大小
|
|
|
+ private final static String KEY_ALGORITHM = "RSA"; //加密算法RSA
|
|
|
+ private final static int MAX_ENCRYPT_BLOCK = 117; //RSA最大加密明文大小
|
|
|
+ public final static String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHEoOi4U/rmwFu6gqn7Sc1IwLX38ncSaonSwkhKyxa44nvvqjyqzHryFb7t5kbANBWrhjhaZ4AmpiODH0hSj9cCJJY2qWrQfeZLt3fWIfED/yZhocImuxb7QZqFjwu2/N7PdGMAPA0pAX4rtQM8iw773iGk6uSBRIDC3IXs3lC9QIDAQAB";
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加密
|
|
|
+ *
|
|
|
+ * @param publicKey 公钥
|
|
|
+ * @param plainText 加密的内容
|
|
|
+ * @return 返回加密后的内容
|
|
|
+ */
|
|
|
+ public static String encrypt(String publicKey, String plainText) {
|
|
|
+ String encryptStr = null;
|
|
|
+ try {
|
|
|
+ encryptStr = RSAUtils.encrypt(RSAUtils.loadPublicKey(publicKey), plainText.getBytes("UTF-8"));
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return encryptStr;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密
|
|
|
+ *
|
|
|
+ * @param privateKey 私钥
|
|
|
+ * @param encryptText 秘文
|
|
|
+ * @return 揭秘后的内容
|
|
|
+ */
|
|
|
+ public static String decrypt(String privateKey, String encryptText) {
|
|
|
+ String decryptStr = null;
|
|
|
+ try {
|
|
|
+ decryptStr = RSAUtils.decrypt(privateKey, RSAUtils.strToBase64(encryptText));
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return decryptStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成RAS公钥与私钥字符串,直接返回
|
|
|
+ */
|
|
|
+ public static HashMap<String, String> getKeys() {
|
|
|
+ HashMap<String, String> map = new HashMap<String, String>();
|
|
|
+ KeyPairGenerator keyPairGen = null;
|
|
|
+ try {
|
|
|
+ keyPairGen = KeyPairGenerator.getInstance("RSA");
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ // TODO Auto-generated catch block
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 初始化密钥对生成器,密钥大小为96-1024位
|
|
|
+ keyPairGen.initialize(1024, new SecureRandom());
|
|
|
+ // 生成一个密钥对,保存在keyPair中
|
|
|
+ KeyPair keyPair = keyPairGen.generateKeyPair();
|
|
|
+ // 得到公钥字符串
|
|
|
+ String publicKey = base64ToStr(keyPair.getPublic().getEncoded());
|
|
|
+ // 得到私钥字符串
|
|
|
+ String privateKey = base64ToStr(keyPair.getPrivate().getEncoded());
|
|
|
+ map.put("publicKey", publicKey);
|
|
|
+ map.put("privateKey", privateKey);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据公钥字符串加载公钥
|
|
|
+ *
|
|
|
+ * @param publicKeyStr 公钥字符串
|
|
|
+ * @return
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ private static RSAPublicKey loadPublicKey(String publicKeyStr) throws Exception {
|
|
|
+ try {
|
|
|
+ byte[] buffer = javax.xml.bind.DatatypeConverter.parseBase64Binary(publicKeyStr);
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
|
|
|
+ return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ throw new Exception("无此算法", e);
|
|
|
+ } catch (InvalidKeySpecException e) {
|
|
|
+ throw new Exception("公钥非法", e);
|
|
|
+ } catch (NullPointerException e) {
|
|
|
+ throw new Exception("公钥数据为空", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 公钥加密
|
|
|
+ *
|
|
|
+ * @param publicKey 公钥
|
|
|
+ * @param plainTextData 明文数据
|
|
|
+ * @return
|
|
|
+ * @throws Exception 加密过程中的异常信息
|
|
|
+ */
|
|
|
+ private static String encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception {
|
|
|
+ if (publicKey == null) {
|
|
|
+ throw new Exception("加密公钥为空, 请设置");
|
|
|
+ }
|
|
|
+ Cipher cipher = null;
|
|
|
+ try {
|
|
|
+ // 使用默认RSA
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
|
+ int inputLen = plainTextData.length;
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
+ int offSet = 0;
|
|
|
+ byte[] cache;
|
|
|
+ int i = 0;
|
|
|
+ // 对数据分段加密
|
|
|
+ while (inputLen - offSet > 0) {
|
|
|
+ if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
|
|
+ cache = cipher.doFinal(plainTextData, offSet, MAX_ENCRYPT_BLOCK);
|
|
|
+ } else {
|
|
|
+ cache = cipher.doFinal(plainTextData, offSet, inputLen - offSet);
|
|
|
+ }
|
|
|
+ out.write(cache, 0, cache.length);
|
|
|
+ i++;
|
|
|
+ offSet = i * MAX_ENCRYPT_BLOCK;
|
|
|
+ }
|
|
|
+ byte[] encryptedData = out.toByteArray();
|
|
|
+ out.close();
|
|
|
+ return Base64.encodeBase64String(encryptedData);
|
|
|
+ } 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("明文数据已损坏");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私钥解密
|
|
|
+ *
|
|
|
+ * @param privateKey 私钥
|
|
|
+ * @param cipherData 密文数据
|
|
|
+ * @return 明文
|
|
|
+ * @throws Exception 解密过程中的异常信息
|
|
|
+ */
|
|
|
+ private static String decrypt(String privateKey, byte[] cipherData) throws Exception {
|
|
|
+
|
|
|
+ if (privateKey == null) {
|
|
|
+ throw new Exception("解密私钥为空, 请设置");
|
|
|
+ }
|
|
|
+ Cipher cipher = null;
|
|
|
+ try {
|
|
|
+ byte[] keyBytes = Base64Utils.decode(privateKey.getBytes("UTF-8"));
|
|
|
+ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
|
|
|
+ Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
|
|
|
+ cipher = Cipher.getInstance(keyFactory.getAlgorithm());
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, privateK);
|
|
|
+ int inputLen = cipherData.length;
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
+ int offSet = 0;
|
|
|
+ byte[] cache;
|
|
|
+ int i = 0;
|
|
|
+ // 对数据分段解密
|
|
|
+ while (inputLen - offSet > 0) {
|
|
|
+ if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
|
|
+ cache = cipher.doFinal(cipherData, offSet, MAX_DECRYPT_BLOCK);
|
|
|
+ } else {
|
|
|
+ cache = cipher.doFinal(cipherData, offSet, inputLen - offSet);
|
|
|
+ }
|
|
|
+ out.write(cache, 0, cache.length);
|
|
|
+ i++;
|
|
|
+ offSet = i * MAX_DECRYPT_BLOCK;
|
|
|
+ }
|
|
|
+ byte[] decryptedData = out.toByteArray();
|
|
|
+ out.close();
|
|
|
+ return new String(decryptedData, "UTF-8");
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
+ throw new Exception("无此解密算法");
|
|
|
+ } catch (NoSuchPaddingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return null;
|
|
|
+ } catch (InvalidKeyException e) {
|
|
|
+ throw new Exception("解密私钥非法,请检查");
|
|
|
+ } catch (IllegalBlockSizeException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new Exception("密文长度非法");
|
|
|
+ } catch (BadPaddingException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw new Exception("密文数据已损坏");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String base64ToStr(byte[] b) {
|
|
|
+ return javax.xml.bind.DatatypeConverter.printBase64Binary(b);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] strToBase64(String str) {
|
|
|
+ return javax.xml.bind.DatatypeConverter.parseBase64Binary(str);
|
|
|
+ }
|
|
|
+
|
|
|
+}
|