RSAUtil.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package com.szwl.model.utils;
  2. import com.szwl.model.utils.constants.Algorithm;
  3. import com.szwl.model.utils.constants.CommonConst;
  4. import com.szwl.model.utils.exceptions.JPException;
  5. import javax.crypto.Cipher;
  6. import java.io.ByteArrayOutputStream;
  7. import java.security.*;
  8. import java.security.spec.PKCS8EncodedKeySpec;
  9. import java.security.spec.X509EncodedKeySpec;
  10. import java.util.HashMap;
  11. import java.util.Map;
  12. /**
  13. * RSA加解密的工具类
  14. * @author chenyf
  15. * @date 2018-12-15
  16. */
  17. public class RSAUtil {
  18. public static final String DEFAULT_ENCRYPT_ALGORITHM = "RSA/ECB/PKCS1Padding";
  19. public static final String SIGNATURE_ALGORITHM_SHA1 = "SHA1withRSA";
  20. public static final String SIGNATURE_ALGORITHM_MD5 = "MD5withRSA";
  21. public static final int KEY_SIZE = 1024;
  22. public static final String PUBLIC_KEY = "publicKey";
  23. public static final String PRIVATE_KEY = "privateKey";
  24. /**
  25. /**
  26. * RSA最大加密明文大小
  27. */
  28. private static final int MAX_ENCRYPT_BLOCK = 116;
  29. /**
  30. /**
  31. * RSA最大解密密文大小
  32. */
  33. private static final int MAX_DECRYPT_BLOCK = 128;
  34. /**
  35. * 生成公私密钥对
  36. * @return
  37. * @throws Exception
  38. */
  39. public static Map<String, String> genKeyPair() throws Exception {
  40. KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(Algorithm.RSA);
  41. keyPairGen.initialize(KEY_SIZE);
  42. KeyPair keyPair = keyPairGen.generateKeyPair();
  43. final Map<String, String> keyMap = new HashMap<String, String>(2);
  44. keyMap.put(PUBLIC_KEY, CodeUtil.base64Encode(keyPair.getPublic().getEncoded()));
  45. keyMap.put(PRIVATE_KEY, CodeUtil.base64Encode(keyPair.getPrivate().getEncoded()));
  46. return keyMap;
  47. }
  48. /**
  49. * 生成RSA签名串
  50. * @param data 需要生成签名串的数据
  51. * @param mchPrivateKey 商户私钥
  52. * @return
  53. * @throws JPException
  54. */
  55. public static String sign(String data, String mchPrivateKey, boolean isSha) throws JPException {
  56. try {
  57. byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
  58. byte[] keyBytes = CodeUtil.base64Decode(mchPrivateKey);
  59. String algorithm = isSha ? SIGNATURE_ALGORITHM_SHA1 : SIGNATURE_ALGORITHM_MD5;
  60. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  61. PrivateKey priKey = KeyFactory.getInstance(Algorithm.RSA).generatePrivate(pkcs8KeySpec);
  62. Signature signature = Signature.getInstance(algorithm);
  63. signature.initSign(priKey);
  64. signature.update(dataBytes);
  65. return HEXUtil.encode(CodeUtil.base64Encode(signature.sign()));
  66. }catch (Throwable e){
  67. throw new JPException("生成RSA签名失败", e);
  68. }
  69. }
  70. /**
  71. * 验证RSA签名串
  72. * @param data 需要验签的数据
  73. * @param jpPublicKey 汇聚公钥
  74. * @param sign 汇聚返回的签名串
  75. * @return
  76. * @throws JPException
  77. */
  78. public static boolean verify(String data, String jpPublicKey, String sign, boolean isSha) throws JPException {
  79. try {
  80. byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
  81. byte[] signBytes = CodeUtil.base64Decode(HEXUtil.decode(sign));
  82. String algorithm = isSha ? SIGNATURE_ALGORITHM_SHA1 : SIGNATURE_ALGORITHM_MD5;
  83. PublicKey publicK = getPublicKey(jpPublicKey);
  84. Signature signature = Signature.getInstance(algorithm);
  85. signature.initVerify(publicK);
  86. signature.update(dataBytes);
  87. return signature.verify(signBytes);
  88. }catch (Throwable e){
  89. throw new JPException("RSA验签失败", e);
  90. }
  91. }
  92. /**
  93. * 使用RSA进行加密
  94. * @param data 需要加密的数据
  95. * @param jpPublicKey 汇聚公钥
  96. * @return
  97. */
  98. public static String encrypt(String data, String jpPublicKey) throws JPException {
  99. try{
  100. byte[] dataBytes = data.getBytes(CommonConst.ENCODING_UTF_8);
  101. dataBytes = doCipher(dataBytes, jpPublicKey, true);
  102. return HEXUtil.encode(CodeUtil.base64Encode(dataBytes));
  103. }catch(Throwable e){
  104. throw new JPException("RSA加密失败", e);
  105. }
  106. }
  107. /**
  108. * 使用RSA进行解密
  109. * @param data 需要解密的数据
  110. * @param mchPrivateKey 商户私钥
  111. * @return
  112. */
  113. public static String decrypt(String data, String mchPrivateKey) throws JPException {
  114. try{
  115. byte[] dataBytes = CodeUtil.base64Decode(HEXUtil.decode(data));
  116. dataBytes = doCipher(dataBytes, mchPrivateKey, false);
  117. return new String(dataBytes, CommonConst.ENCODING_UTF_8);
  118. }catch(Throwable e){
  119. throw new JPException("RSA解密失败", e);
  120. }
  121. }
  122. private static byte[] doCipher(byte[] dataBytes, String keyStr, boolean isEncrypt) throws Exception{
  123. Key key;
  124. Cipher cipher;
  125. int maxBlock;
  126. if(isEncrypt){
  127. maxBlock = MAX_ENCRYPT_BLOCK;
  128. key = getPublicKey(keyStr);
  129. cipher = Cipher.getInstance(DEFAULT_ENCRYPT_ALGORITHM);
  130. cipher.init(Cipher.ENCRYPT_MODE, key);
  131. }else{
  132. maxBlock = MAX_DECRYPT_BLOCK;
  133. byte[] keyBytes = CodeUtil.base64Decode(keyStr);
  134. PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
  135. KeyFactory keyFactory = KeyFactory.getInstance(Algorithm.RSA);
  136. Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
  137. cipher = Cipher.getInstance(keyFactory.getAlgorithm());
  138. cipher.init(Cipher.DECRYPT_MODE, privateK);
  139. }
  140. int offSet = 0, i = 0, inputLen = dataBytes.length;
  141. byte[] cache;
  142. ByteArrayOutputStream out = new ByteArrayOutputStream();
  143. try{
  144. // 对数据分段加密/解密
  145. while (inputLen - offSet > 0) {
  146. if (inputLen - offSet > maxBlock) {
  147. cache = cipher.doFinal(dataBytes, offSet, maxBlock);
  148. } else {
  149. cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
  150. }
  151. out.write(cache, 0, cache.length);
  152. i++;
  153. offSet = i * maxBlock;
  154. }
  155. return out.toByteArray();
  156. } finally {
  157. out.close();
  158. }
  159. }
  160. private static PublicKey getPublicKey(String publicKey) throws Exception{
  161. byte[] keyBytes = CodeUtil.base64Decode(publicKey);
  162. X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
  163. KeyFactory keyFactory = KeyFactory.getInstance(Algorithm.RSA);
  164. return keyFactory.generatePublic(x509KeySpec);
  165. }
  166. }