EncryptTools.java 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package com.pj.api.pushfee.tools;
  2. import cn.hutool.core.codec.Base64;
  3. import cn.hutool.core.util.CharsetUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.crypto.SecureUtil;
  6. import cn.hutool.crypto.asymmetric.KeyType;
  7. import cn.hutool.crypto.asymmetric.RSA;
  8. import cn.hutool.crypto.digest.DigestUtil;
  9. import cn.hutool.crypto.symmetric.AES;
  10. import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
  11. import com.google.gson.Gson;
  12. import com.google.gson.GsonBuilder;
  13. import com.pj.api.pushfee.tools.message.CuMessage;
  14. import com.pj.api.pushfee.tools.message.Header;
  15. import com.pj.api.pushfee.tools.message.Inter;
  16. import com.pj.api.pushfee.tools.message.MessageInter;
  17. public class EncryptTools {
  18. private String sysId;
  19. private String remotePublicKey;
  20. private String localPrivateKey;
  21. private RSA rsaInstance;
  22. private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
  23. /**
  24. * 构造加密工具
  25. * @param sysId 系统Id,由统一计费系统分配
  26. * @param remotePublicKey 对方的公钥
  27. */
  28. public EncryptTools(String sysId, String remotePublicKey) {
  29. this.sysId = sysId;
  30. this.remotePublicKey = remotePublicKey;
  31. rsaInstance = SecureUtil.rsa(null, this.remotePublicKey);
  32. }
  33. /**
  34. * 构造解密工具
  35. * @param localPrivateKey 己方的私钥
  36. */
  37. public EncryptTools(String localPrivateKey) {
  38. this.localPrivateKey = localPrivateKey;
  39. rsaInstance = SecureUtil.rsa(this.localPrivateKey, null);
  40. }
  41. /**
  42. * 生成RSA密钥对
  43. */
  44. public static void generateKeyPairs(){
  45. RSA rsa = new RSA();
  46. // 获取公钥
  47. String pubKey = rsa.getPublicKeyBase64();
  48. System.out.println("公钥:" + pubKey);
  49. // 获取私钥
  50. String priKey = rsa.getPrivateKeyBase64();
  51. System.out.println("私钥:" + priKey);
  52. }
  53. /**
  54. * md5签名
  55. * @param text
  56. * @return
  57. */
  58. private String md5(String text){
  59. return DigestUtil.md5Hex(text);
  60. }
  61. /**
  62. * RSA私钥解密
  63. * @return
  64. */
  65. private String decryptStrByPrivateKey(String encrypt){
  66. try {
  67. return this.rsaInstance.decryptStr(encrypt, KeyType.PrivateKey);
  68. } catch (Exception e) {
  69. throw new RuntimeException("RSA私钥解密失败");
  70. }
  71. }
  72. /**
  73. * RSA公钥加密
  74. * @param text
  75. * @return
  76. */
  77. private String encryptByPublicKey(String text){
  78. try {
  79. return this.rsaInstance.encryptBase64(StrUtil.bytes(text,CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
  80. } catch (Exception e) {
  81. throw new RuntimeException("RSA公钥加密失败");
  82. }
  83. }
  84. /**
  85. * 生成随机秘钥
  86. */
  87. private String getRandomKey(){
  88. return Base64.encode(SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded());
  89. }
  90. private String encodeByAES(String content, String randomKey){
  91. try {
  92. AES aes = SecureUtil.aes(Base64.decode(randomKey));
  93. return aes.encryptBase64(content);
  94. } catch (Exception e) {
  95. throw new RuntimeException("AES加密报文失败");
  96. }
  97. }
  98. private String decodeByAES(String sourceText, String randomKey){
  99. try {
  100. AES aes = SecureUtil.aes(Base64.decode(randomKey));
  101. return aes.decryptStr(sourceText);
  102. } catch (Exception e) {
  103. throw new RuntimeException("AES解密报文失败");
  104. }
  105. }
  106. private boolean verifySignature(CuMessage message){
  107. String signature = message.getSignature();
  108. return md5(gson.toJson(message.getHeader())).equals(signature);
  109. }
  110. /**
  111. * 加密报文
  112. */
  113. public String encryptMessage(MessageInter payLoad){
  114. //生成随机秘钥
  115. String randomKey = getRandomKey();
  116. //加密报文payLoad
  117. String encrypted = encodeByAES(gson.toJson(payLoad), randomKey);
  118. //加密随机秘钥
  119. String keyEncrypted = encryptByPublicKey(randomKey);
  120. Inter interAnnotation = payLoad.getClass().getAnnotation(Inter.class);
  121. String interId = interAnnotation.name();
  122. Header header = new Header(this.sysId, encrypted, keyEncrypted, interId);
  123. //签名:md5提取摘要
  124. String signature = md5(gson.toJson(header));
  125. CuMessage cuMessage = new CuMessage(header, signature);
  126. String msg = gson.toJson(cuMessage);
  127. System.out.println("密文:" + msg);
  128. return msg;
  129. }
  130. /**
  131. * 解密报文
  132. * @return
  133. */
  134. public MessageInter decryptMessage(String text){
  135. CuMessage cuMessage = gson.fromJson(text, CuMessage.class);
  136. return decryptMessage(cuMessage);
  137. }
  138. public MessageInter decryptMessage(CuMessage message){
  139. //验签
  140. if (!verifySignature(message)) {
  141. throw new RuntimeException("验签失败");
  142. }
  143. //用公钥解密得到randomKey
  144. String key = decryptStrByPrivateKey(message.getHeader().getKeyEncrypted());
  145. //用randomKey解密报文
  146. String originText = decodeByAES(message.getHeader().getEncrypted(), key);
  147. MessageInter inter = gson.fromJson(originText, InterEnum.findClass(message.getHeader().getInterId()));
  148. System.out.println("解密:" + originText);
  149. return inter;
  150. }
  151. }