|
@@ -0,0 +1,658 @@
|
|
|
|
+package com.hrsk.cloud.eg.domain.common;
|
|
|
|
+
|
|
|
|
+import org.apache.commons.codec.binary.Base64;
|
|
|
|
+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.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 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 = Base64Utils.encode(publicKey.getEncoded());
|
|
|
|
+ // 得到私钥字符串
|
|
|
|
+ String privateKeyString = 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 = Base64Utils.encode(publicKey.getEncoded());
|
|
|
|
+ // 得到私钥字符串
|
|
|
|
+ String privateKeyString = 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 in
|
|
|
|
+ * 公钥输入流
|
|
|
|
+ * @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);
|
|
|
|
+ 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 privateKey
|
|
|
|
+ * rsa私钥字符串
|
|
|
|
+ * @param charset
|
|
|
|
+ * 字符编码
|
|
|
|
+ * @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) );
|
|
|
|
+
|
|
|
|
+ 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 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) );
|
|
|
|
+ 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 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);
|
|
|
|
+ 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) );
|
|
|
|
+ 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);
|
|
|
|
+ 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) );
|
|
|
|
+ return bverify;
|
|
|
|
+
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
|
|
|
+ System.out.println("genKeyPair:"+genKeyPair());
|
|
|
|
+
|
|
|
|
+ String publickey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQChtoeuzYBROzA+uYWX8O+kQHKUKeACAba/LhEssZNWZ+j5MePVGF7zGtmHwpiftSQpmWT92aKm/wqj4h2J8TPT1fRfp9LOhOglaux4X4xr9duAjWtPpvwezswVCP/kFUSCeIzZyfRqV3KL3unHtxCrEPph0ojFtFXAdZAorJDpjwIDAQAB";
|
|
|
|
+ String pricatekey = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKG2h67NgFE7MD65hZfw76RAcpQp4AIBtr8uESyxk1Zn6Pkx49UYXvMa2YfCmJ+1JCmZZP3Zoqb/CqPiHYnxM9PV9F+n0s6E6CVq7HhfjGv124CNa0+m/B7OzBUI/+QVRIJ4jNnJ9GpXcove6ce3EKsQ+mHSiMW0VcB1kCiskOmPAgMBAAECgYBh0wZfQydVfGWh/B6JnJGLHgVyBabh7+F540c2bzF++prfbEOzm+uMSni+/IPRUQXQOF/0hBw1w2DPZLCTypqbmz+dnBj6txWBUt1Z87gEgIXzLGd9s7+d/rfsTaKayi/UOOZ45h4UiZlSnTlHYr0PZMK35yDVmDKXVysONwEw+QJBANme7Ls42x3QnmFQ4S6m43wSu+PEJ4VRgSqyCmT63vdf34jk4zLTyGRnCjrmKKsLEtqX34VJdosHTZSxJRRCk1sCQQC+O393VtxN88IA10HewN35NBI+tzPWScpD6681Q7LGRr8FTzcdSoX9xyQ5ySCFuEltj9DN4pI2vi66we8u2VzdAkEAo3PCyzyBF3vB+cYN3ERtSJuplAGYzYHSSoc/V2k2Xwcblm6UV3DKat8Zx/NnSFEg8B5yPGJZL0Nk+fGzr+vxUQJBAIqOX3sWowOMBcQDBREvvP2jtZ5EZdcwi8gIw+ax1magZMWDOwt0mj+LapFEMxHydlj8pQMwgXqp7vNMCeA/pWkCQQDDaseYvTEtGoRUBsjHZdWvyzFbBi/dGyYKE7YH4bo+cjp6vJKEIN30WVmu0mOTaTjoXtP7GrQ3gcOrTfXmRDJo";
|
|
|
|
+ RSAPublicKey publicKey = null;
|
|
|
|
+ try {
|
|
|
|
+ publicKey = RSAUtils.getPublicKey(publickey);
|
|
|
|
+ } catch (NoSuchAlgorithmException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ } catch (InvalidKeySpecException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ System.out.println("publicKey:"+publicKey);
|
|
|
|
+ String d="15036521585";
|
|
|
|
+ String s = publicEncrypt(d, publicKey);
|
|
|
|
+ System.out.println("公钥加密:"+s);
|
|
|
|
+
|
|
|
|
+ RSAPrivateKey privateKey = RSAUtils.getPrivateKey(pricatekey);
|
|
|
|
+// RSAPrivateKey privateKey = RSAUtils.getPrivateKey("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALjLu7GbJMOCCaIfoghRIzWb0brsByRF8PYwHQWRmjXKusHoBta37ej38zKkMly/4rfUPt4G05ovFOXMXGg1NQ+CUcVL6mcDnyqTTZtF5HJ0etgFabhPjHbqixalxPjkBay3y/dL+kGkdpdNQTaP9lzH6OZiD/HcmQnrpc6Q5thHAgMBAAECgYBtt9Dt535RciDEGGH87CeqiaRhhgfLepdRpElm6AcWTxLJVDjTPYtM2gKUG7cnKGq02Jim/IigL7oJomdvG8AvO5dJstMXCJTnSsp7Yj/f1MZ0K6Y6J1FflDcoW16Naz0Uo4xLM1jMfj2Mqd6MKzprSawTz5to3OB+8PYa3sDtwQJBAPhCs+Yi0O5Pl7U1ShIPUuoA69b24ecx131RigqlFZbDSMU2ZFRF2lunvIHPp+3fTAvWBZr4symqPj3+NsQsB6cCQQC+jolT2lnQaiyErFHhw05yHKabSnZ5VMtZ/utBmLb6yxyh5f+1qC411xRGEFL7VqmMFVDSdvK/bJbq2nGuZr5hAkABybkx9x46GSimjXOzHZkjRk5sheqql5lNtcCgwv+czls/0Fx4nugrsNGSvcQf2nPZwfjYXOItcqRwHdyXHRoRAkBp8G5ymtsB3nU/kVm4bM9o63rIrN4u2DBxqSJ7hn578X3KmEbQZF7Eef2AckTgDK8X/SXAzHZqa+F/UdCPx/khAkEArPNa/nE0wT59kVeQm5V9I/La/jrTSDjOqYzqZrI3VVsfouqgbnv0q1Hd4Qdo58ei9mBm6jZersfUUbUkS4/Vfg==");
|
|
|
|
+ String s1 = privateDecrypt(s, privateKey);
|
|
|
|
+ System.out.println("私钥解密:"+s1);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+}
|