|
@@ -0,0 +1,634 @@
|
|
|
|
+package com.hrsk.cloud.eg.infrastructure.utils;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
+import org.apache.tomcat.util.http.fileupload.IOUtils;
|
|
|
|
+import org.springframework.util.Base64Utils;
|
|
|
|
+import sun.misc.BASE64Decoder;
|
|
|
|
+
|
|
|
|
+import javax.crypto.BadPaddingException;
|
|
|
|
+import javax.crypto.Cipher;
|
|
|
|
+import javax.crypto.IllegalBlockSizeException;
|
|
|
|
+import javax.crypto.NoSuchPaddingException;
|
|
|
|
+import java.io.*;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.security.*;
|
|
|
|
+import java.security.interfaces.RSAPrivateKey;
|
|
|
|
+import java.security.interfaces.RSAPublicKey;
|
|
|
|
+import java.security.spec.InvalidKeySpecException;
|
|
|
|
+import java.security.spec.PKCS8EncodedKeySpec;
|
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+public class RSAUtils {
|
|
|
|
+ /**
|
|
|
|
+ * 字节数据转字符串专用集合
|
|
|
|
+ */
|
|
|
|
+ private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
|
|
|
|
+ '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
|
|
|
+ public static final String CHARSET = "UTF-8";
|
|
|
|
+ public static final String RSA_ALGORITHM = "RSA";
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 加密的公钥 私钥 返回对应字符串
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String genKeyPair( ) {
|
|
|
|
+
|
|
|
|
+ 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();
|
|
|
|
+ // 得到私钥
|
|
|
|
+ RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
|
|
|
+ // 得到公钥
|
|
|
|
+ RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
|
|
|
+
|
|
|
|
+ // 得到公钥字符串
|
|
|
|
+ String publicKeyString =new String(Base64Utils.encode(publicKey.getEncoded()));
|
|
|
|
+ // 得到私钥字符串
|
|
|
|
+ String privateKeyString =new String(Base64Utils.encode(privateKey.getEncoded()));
|
|
|
|
+ return publicKeyString+","+privateKeyString;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 随机生成密钥对
|
|
|
|
+ */
|
|
|
|
+ public static void genKeyPair(String filePath) {
|
|
|
|
+ // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
|
|
|
|
+ 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();
|
|
|
|
+ // 得到私钥
|
|
|
|
+ RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
|
|
|
+ // 得到公钥
|
|
|
|
+ RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
|
|
|
+ try {
|
|
|
|
+ // 得到公钥字符串
|
|
|
|
+ String publicKeyString = new String(Base64Utils.encode(publicKey.getEncoded()));
|
|
|
|
+ // 得到私钥字符串
|
|
|
|
+ String privateKeyString =new String(Base64Utils.encode(privateKey.getEncoded()));
|
|
|
|
+ // 将密钥对写入到文件
|
|
|
|
+ FileWriter pubfw = new FileWriter(filePath + "/publicKey.key");
|
|
|
|
+ FileWriter prifw = new FileWriter(filePath + "/privateKey.key");
|
|
|
|
+ BufferedWriter pubbw = new BufferedWriter(pubfw);
|
|
|
|
+ BufferedWriter pribw = new BufferedWriter(prifw);
|
|
|
|
+ pubbw.write(publicKeyString);
|
|
|
|
+ pribw.write(privateKeyString);
|
|
|
|
+ pubbw.flush();
|
|
|
|
+ pubbw.close();
|
|
|
|
+ pubfw.close();
|
|
|
|
+ pribw.flush();
|
|
|
|
+ pribw.close();
|
|
|
|
+ prifw.close();
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 从文件中输入流中加载公钥
|
|
|
|
+ *
|
|
|
|
+ * @param
|
|
|
|
+ *
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 加载公钥时产生的异常
|
|
|
|
+ */
|
|
|
|
+ public static String loadPublicKeyByFile(String path) throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ BufferedReader br = new BufferedReader(new FileReader(path));
|
|
|
|
+ String readLine = null;
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ while ((readLine = br.readLine()) != null) {
|
|
|
|
+ sb.append(readLine);
|
|
|
|
+ }
|
|
|
|
+ br.close();
|
|
|
|
+ return sb.toString();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new Exception("公钥数据流读取错误");
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ throw new Exception("公钥输入流为空");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 从字符串中加载公钥
|
|
|
|
+ *
|
|
|
|
+ * @param publicKeyStr
|
|
|
|
+ * 公钥数据字符串
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 加载公钥时产生的异常
|
|
|
|
+ */
|
|
|
|
+ public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
|
|
|
|
+ throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ byte[] buffer = Base64Utils.decode(publicKeyStr.getBytes(StandardCharsets.UTF_8));
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
|
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
|
|
|
|
+ return (RSAPublicKey) keyFactory.generatePublic(keySpec);
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
+ throw new Exception("无此算法");
|
|
|
|
+ } catch (InvalidKeySpecException e) {
|
|
|
|
+ throw new Exception("公钥非法");
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ throw new Exception("公钥数据为空");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 从文件中加载私钥
|
|
|
|
+ *
|
|
|
|
+ * 私钥文件名
|
|
|
|
+ * @return 是否成功
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public static String loadPrivateKeyByFile(String path) throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ BufferedReader br = new BufferedReader(new FileReader(path));
|
|
|
|
+ String readLine = null;
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
+ while ((readLine = br.readLine()) != null) {
|
|
|
|
+ sb.append(readLine);
|
|
|
|
+ }
|
|
|
|
+ br.close();
|
|
|
|
+ return sb.toString();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new Exception("私钥数据读取错误");
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ throw new Exception("私钥输入流为空");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
|
|
|
|
+ throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ BASE64Decoder base64Decoder = new BASE64Decoder();
|
|
|
|
+ byte[] buffer = base64Decoder.decodeBuffer(privateKeyStr);
|
|
|
|
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
|
+ return (RSAPrivateKey) keyFactory
|
|
|
|
+ .generatePrivate(keySpec);
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
+ throw new Exception("无此算法");
|
|
|
|
+ } catch (InvalidKeySpecException e) {
|
|
|
|
+ throw new Exception("私钥非法");
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new Exception("私钥数据内容读取错误");
|
|
|
|
+ } catch (NullPointerException e) {
|
|
|
|
+ throw new Exception("私钥数据为空");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 得到公钥
|
|
|
|
+ *
|
|
|
|
+ * @param publicKey 密钥字符串(经过base64编码)
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
|
|
+ //通过X509编码的Key指令获得公钥对象
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
|
|
|
+ X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
|
|
|
|
+ RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
|
|
|
|
+ return key;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 得到私钥
|
|
|
|
+ * @param privateKey 密钥字符串(经过base64编码)
|
|
|
|
+ * @throws Exception
|
|
|
|
+ */
|
|
|
|
+ public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
|
|
+ //通过PKCS#8编码的Key指令获得私钥对象
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
|
|
|
|
+ PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
|
|
|
|
+ RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
|
|
|
|
+ return key;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 公钥加密
|
|
|
|
+ * @param data
|
|
|
|
+ * @param publicKey
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static String publicEncrypt(String data, RSAPublicKey publicKey) {
|
|
|
|
+ try {
|
|
|
|
+ Cipher cipher = Cipher.getInstance("RSA");
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
|
|
+ return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public static String publicEncryptUnsafe(String data, RSAPublicKey publicKey) {
|
|
|
|
+ try {
|
|
|
|
+ Cipher cipher = Cipher.getInstance("RSA");
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
|
|
+ return Base64.encodeBase64String(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), publicKey.getModulus().bitLength()));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 私钥解密
|
|
|
|
+ * @param data
|
|
|
|
+ * @param privateKey
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+ public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
|
|
|
|
+ try {
|
|
|
|
+ Cipher cipher = Cipher.getInstance("RSA");
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
|
|
+ return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), "UTF-8");
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //rsa切割解码 , ENCRYPT_MODE,加密数据 ,DECRYPT_MODE,解密数据
|
|
|
|
+ private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
|
|
|
|
+ int maxBlock = 0; //最大块
|
|
|
|
+ if (opmode == Cipher.DECRYPT_MODE) {
|
|
|
|
+ maxBlock = keySize / 8;
|
|
|
|
+ } else {
|
|
|
|
+ maxBlock = keySize / 8 - 11;
|
|
|
|
+ }
|
|
|
|
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
|
|
+ int offSet = 0;
|
|
|
|
+ byte[] buff;
|
|
|
|
+ int i = 0;
|
|
|
|
+ try {
|
|
|
|
+ while (datas.length > offSet) {
|
|
|
|
+ if (datas.length - offSet > maxBlock) {
|
|
|
|
+ //可以调用以下的doFinal()方法完成加密或解密数据:
|
|
|
|
+ buff = cipher.doFinal(datas, offSet, maxBlock);
|
|
|
|
+ } else {
|
|
|
|
+ buff = cipher.doFinal(datas, offSet, datas.length - offSet);
|
|
|
|
+ }
|
|
|
|
+ out.write(buff, 0, buff.length);
|
|
|
|
+ i++;
|
|
|
|
+ offSet = i * maxBlock;
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
|
|
|
|
+ }
|
|
|
|
+ byte[] resultDatas = out.toByteArray();
|
|
|
|
+ IOUtils.closeQuietly(out);
|
|
|
|
+ return resultDatas;
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 公钥加密过程
|
|
|
|
+ *
|
|
|
|
+ * @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 {
|
|
|
|
+ // 使用默认RSA
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
+ // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
|
|
|
|
+ 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("明文数据已损坏");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 私钥加密过程
|
|
|
|
+ *
|
|
|
|
+ * @param privateKey
|
|
|
|
+ * 私钥
|
|
|
|
+ * @param plainTextData
|
|
|
|
+ * 明文数据
|
|
|
|
+ * @return
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 加密过程中的异常信息
|
|
|
|
+ */
|
|
|
|
+ public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
|
|
|
|
+ throws Exception {
|
|
|
|
+ if (privateKey == null) {
|
|
|
|
+ throw new Exception("加密私钥为空, 请设置");
|
|
|
|
+ }
|
|
|
|
+ Cipher cipher = null;
|
|
|
|
+ try {
|
|
|
|
+ // 使用默认RSA
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
+ cipher.init(Cipher.ENCRYPT_MODE, privateKey);
|
|
|
|
+ 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("明文数据已损坏");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 私钥解密过程
|
|
|
|
+ *
|
|
|
|
+ * @param privateKey
|
|
|
|
+ * 私钥
|
|
|
|
+ * @param cipherData
|
|
|
|
+ * 密文数据
|
|
|
|
+ * @return 明文
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 解密过程中的异常信息
|
|
|
|
+ */
|
|
|
|
+ public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
|
|
|
|
+ throws Exception {
|
|
|
|
+ if (privateKey == null) {
|
|
|
|
+ throw new Exception("解密私钥为空, 请设置");
|
|
|
|
+ }
|
|
|
|
+ Cipher cipher = null;
|
|
|
|
+ try {
|
|
|
|
+ // 使用默认RSA
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
+ // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
|
|
+ byte[] output = cipher.doFinal(cipherData);
|
|
|
|
+ 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("密文数据已损坏");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 公钥解密过程
|
|
|
|
+ *
|
|
|
|
+ * @param publicKey
|
|
|
|
+ * 公钥
|
|
|
|
+ * @param cipherData
|
|
|
|
+ * 密文数据
|
|
|
|
+ * @return 明文
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 解密过程中的异常信息
|
|
|
|
+ */
|
|
|
|
+ public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
|
|
|
|
+ throws Exception {
|
|
|
|
+ if (publicKey == null) {
|
|
|
|
+ throw new Exception("解密公钥为空, 请设置");
|
|
|
|
+ }
|
|
|
|
+ Cipher cipher = null;
|
|
|
|
+ try {
|
|
|
|
+ // 使用默认RSA
|
|
|
|
+ cipher = Cipher.getInstance("RSA");
|
|
|
|
+ // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
|
|
|
|
+ cipher.init(Cipher.DECRYPT_MODE, publicKey);
|
|
|
|
+ byte[] output = cipher.doFinal(cipherData);
|
|
|
|
+ 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("密文数据已损坏");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 字节数据转十六进制字符串
|
|
|
|
+ *
|
|
|
|
+ * @param data
|
|
|
|
+ * 输入数据
|
|
|
|
+ * @return 十六进制内容
|
|
|
|
+ */
|
|
|
|
+ public static String byteArrayToString(byte[] data) {
|
|
|
|
+ StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
+ for (int i = 0; i < data.length; i++) {
|
|
|
|
+ // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
|
|
|
|
+ stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
|
|
|
|
+ // 取出字节的低四位 作为索引得到相应的十六进制标识符
|
|
|
|
+ stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
|
|
|
|
+ if (i < data.length - 1) {
|
|
|
|
+ stringBuilder.append(' ');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return stringBuilder.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 签名算法
|
|
|
|
+ */
|
|
|
|
+ public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * rsa签名
|
|
|
|
+ *
|
|
|
|
+ * @param content
|
|
|
|
+ * 待签名的字符串
|
|
|
|
+ * @param
|
|
|
|
+ *
|
|
|
|
+ * @param
|
|
|
|
+ *
|
|
|
|
+ * @return 签名结果
|
|
|
|
+ * @throws Exception
|
|
|
|
+ * 签名失败则抛出异常
|
|
|
|
+ */
|
|
|
|
+ public static byte[] rsaSign(String content, RSAPrivateKey priKey)
|
|
|
|
+ throws SignatureException {
|
|
|
|
+ try {
|
|
|
|
+
|
|
|
|
+ Signature signature = Signature.getInstance("SHA1withRSA");
|
|
|
|
+ signature.initSign(priKey);
|
|
|
|
+ signature.update(content.getBytes("utf-8"));
|
|
|
|
+
|
|
|
|
+ byte[] signed = signature.sign();
|
|
|
|
+ return signed;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new SignatureException("RSAcontent = " + content
|
|
|
|
+ + "; charset = ", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * rsa验签
|
|
|
|
+ *
|
|
|
|
+ * @param content
|
|
|
|
+ * 被签名的内容
|
|
|
|
+ * @param sign
|
|
|
|
+ * 签名后的结果
|
|
|
|
+ * @return 验签结果
|
|
|
|
+ * @throws SignatureException
|
|
|
|
+ * 验签失败,则抛异常
|
|
|
|
+ */
|
|
|
|
+ public static boolean doCheck(String content, byte[] sign, RSAPublicKey pubKey)
|
|
|
|
+ throws SignatureException {
|
|
|
|
+ try {
|
|
|
|
+ Signature signature = Signature.getInstance("SHA1withRSA");
|
|
|
|
+ signature.initVerify(pubKey);
|
|
|
|
+ signature.update(content.getBytes("utf-8"));
|
|
|
|
+ return signature.verify((sign));
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ throw new SignatureException("RSA验证签名[content = " + content
|
|
|
|
+ + "; charset = " + "; signature = " + sign + "]发生异常!", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * RSA签名
|
|
|
|
+ * @param content 待签名数据
|
|
|
|
+ * @param privateKey 商户私钥
|
|
|
|
+ * @param encode 字符集编码
|
|
|
|
+ * @return 签名值
|
|
|
|
+ */
|
|
|
|
+ public static String sign(String content, String privateKey, String encode) {
|
|
|
|
+ try {
|
|
|
|
+ PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64Utils.decode(privateKey.getBytes(StandardCharsets.UTF_8)) );
|
|
|
|
+
|
|
|
|
+ KeyFactory keyf = KeyFactory.getInstance("RSA");
|
|
|
|
+ PrivateKey priKey = keyf.generatePrivate(priPKCS8);
|
|
|
|
+
|
|
|
|
+ Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
|
|
|
|
+
|
|
|
|
+ signature.initSign(priKey);
|
|
|
|
+ signature.update( content.getBytes(encode));
|
|
|
|
+
|
|
|
|
+ byte[] signed = signature.sign();
|
|
|
|
+
|
|
|
|
+ return new String(Base64Utils.encode(signed));
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static String sign(String content, String privateKey) {
|
|
|
|
+ try {
|
|
|
|
+ PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec( Base64Utils.decode(privateKey.getBytes(StandardCharsets.UTF_8)) );
|
|
|
|
+ KeyFactory keyf = KeyFactory.getInstance("RSA");
|
|
|
|
+ PrivateKey priKey = keyf.generatePrivate(priPKCS8);
|
|
|
|
+ Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
|
|
|
|
+ signature.initSign(priKey);
|
|
|
|
+ signature.update( content.getBytes());
|
|
|
|
+ byte[] signed = signature.sign();
|
|
|
|
+ return new String(Base64Utils.encode(signed));
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * RSA验签名检查
|
|
|
|
+ * @param content 待签名数据
|
|
|
|
+ * @param sign 签名值
|
|
|
|
+ * @param publicKey 分配给开发商公钥
|
|
|
|
+ * @param encode 字符集编码
|
|
|
|
+ * @return 布尔值
|
|
|
|
+ */
|
|
|
|
+ public static boolean doCheck(String content, String sign, String publicKey, String encode) {
|
|
|
|
+ try {
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
|
+ byte[] encodedKey = Base64Utils.decode(publicKey.getBytes(StandardCharsets.UTF_8));
|
|
|
|
+ PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Signature signature = Signature
|
|
|
|
+ .getInstance(SIGN_ALGORITHMS);
|
|
|
|
+
|
|
|
|
+ signature.initVerify(pubKey);
|
|
|
|
+ signature.update( content.getBytes(encode) );
|
|
|
|
+
|
|
|
|
+ boolean bverify = signature.verify( Base64Utils.decode(sign.getBytes(StandardCharsets.UTF_8)) );
|
|
|
|
+ return bverify;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ catch (Exception e)
|
|
|
|
+ {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static boolean doCheck(String content, String sign, String publicKey) {
|
|
|
|
+ try {
|
|
|
|
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
|
|
+ byte[] encodedKey = Base64Utils.decode(publicKey.getBytes(StandardCharsets.UTF_8));
|
|
|
|
+ PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ Signature signature = Signature
|
|
|
|
+ .getInstance(SIGN_ALGORITHMS);
|
|
|
|
+
|
|
|
|
+ signature.initVerify(pubKey);
|
|
|
|
+ signature.update( content.getBytes() );
|
|
|
|
+
|
|
|
|
+ boolean bverify = signature.verify( Base64Utils.decode(sign.getBytes(StandardCharsets.UTF_8)) );
|
|
|
|
+ return bverify;
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+}
|