SignUtils.java 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package com.logosdata.security.util;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.logosdata.security.SM2;
  4. import com.logosdata.security.SM3;
  5. import com.logosdata.security.SM4;
  6. import lombok.extern.slf4j.Slf4j;
  7. import org.bouncycastle.math.ec.ECPoint;
  8. import java.io.ByteArrayInputStream;
  9. import java.io.ObjectInputStream;
  10. import java.math.BigInteger;
  11. import java.util.Base64;
  12. import java.util.HashMap;
  13. import java.util.Map;
  14. import java.util.Properties;
  15. /**
  16. * {@code SignUtils} 签名工具类
  17. *
  18. * @author Hengchen.Sun
  19. * @version 1.0.0
  20. * @date 2021-02-18
  21. * @since ver.1.0.0
  22. */
  23. @Slf4j
  24. public final class SignUtils {
  25. private SignUtils(){}
  26. /**
  27. * 通用解密方法
  28. * @param json
  29. * @param secretKey
  30. * @return
  31. * @throws Exception
  32. */
  33. public static String decryptData(String json, String secretKey) throws Exception {
  34. JSONObject jsonObject = JSONObject.parseObject(json);
  35. String decData = null;
  36. SM4 sm4 = new SM4();
  37. sm4.setSecretKey(secretKey);
  38. sm4.setHexString(false);
  39. // 响应业务报文data
  40. String dataString =jsonObject.getString("data");
  41. decData = sm4.decryptDataToString_ECB(dataString, "UTF-8");
  42. // 响应签名sign
  43. String signString = jsonObject.getString("sign");
  44. byte[] sign = Base64.getDecoder().decode(signString.getBytes());
  45. Object signature1 =toObject(sign);
  46. log.info("签名:" + signature1.toString());
  47. String[] arr = signature1.toString().split(",");
  48. BigInteger r = new BigInteger(arr[0], 16);
  49. BigInteger s = new BigInteger(arr[1], 16);
  50. SM2.Signature signature = new SM2.Signature(r, s);
  51. System.err.println(signature);
  52. // sm2加密
  53. SM2 sm2 = new SM2();
  54. // 读取公钥
  55. ECPoint publicKey = sm2.importPublicKey(getConfigPublicKey().get("publicKey").toString());
  56. String IDA = "taxhelper";
  57. log.info("签名信息:" + decData);
  58. byte[] hash = SM3.hash(decData.getBytes("UTF-8"));
  59. // 验签
  60. boolean flag = sm2.verify(new String(hash), signature, IDA, publicKey);
  61. System.out.println(flag);
  62. if (flag) {
  63. log.info("验证签名成功");
  64. return decData;
  65. } else {
  66. log.info("验证签名失败");
  67. // String errorMsg = "{\"message\":\"验证签名失败\"}";
  68. String errorMsg = "验证签名失败";
  69. throw new RuntimeException(errorMsg);
  70. }
  71. }
  72. /**
  73. * 通用加密方法
  74. * @param param
  75. * @param secretKey
  76. * @return
  77. * @throws Exception
  78. */
  79. public static Map<String, Object> encryptData(Map<String, Object> param, String secretKey) throws Exception {
  80. Map<String, Object> newParam = new HashMap<>();
  81. JSONObject jsonObject = new JSONObject();
  82. jsonObject.putAll(param);
  83. String decData = jsonObject.toString();
  84. SM4 sm4 = new SM4();
  85. // 加密密钥,由双方协定产生
  86. sm4.setSecretKey(secretKey);
  87. sm4.setHexString(false);
  88. log.info("ECB模式加密");
  89. String encData = sm4.encryptDataToString_ECB(decData, "UTF-8");
  90. log.info("密文: " + encData);
  91. byte[] hash = SM3.hash(decData.getBytes("UTF-8"));
  92. SM2 sm2 = new SM2();
  93. ECPoint publicKey = sm2.importPublicKey(getConfigPublicKey().get("publicKey").toString());
  94. byte[] sign = sm2.encrypt(hash, publicKey);
  95. newParam = new HashMap<>();
  96. newParam.put("data", encData);
  97. newParam.put("sign", Base64.getEncoder().encodeToString(sign));
  98. log.info("data:" + encData);
  99. log.info("sign:" + Base64.getEncoder().encodeToString(sign));
  100. return newParam;
  101. }
  102. public static Object toObject(byte[] bytes) throws Exception {
  103. Object obj = null;
  104. try {
  105. // bytearray to object
  106. ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
  107. ObjectInputStream oi = new ObjectInputStream(bi);
  108. obj = oi.readObject();
  109. log.error("签名对象:", obj);
  110. bi.close();
  111. oi.close();
  112. } catch (Exception e) {
  113. System.out.println("translation" + e.getMessage());
  114. e.printStackTrace();
  115. }
  116. return obj;
  117. }
  118. public static Map<String, Object> getConfigPublicKey() {
  119. Map<String, Object> map = new HashMap<String, Object>();
  120. Properties props = System.getProperties(); // 获得系统属性集
  121. String osName = props.getProperty("os.name").toLowerCase(); // 操作系统名称
  122. if (osName.indexOf("linux") != -1 || osName.indexOf("unix") != -1) {
  123. // map.put("publicKey", "/home/logos/dzdk-api-gateway/publickey.pem");
  124. // map.put("privateKey", "/home/logos/dzdk-api-gateway/privatekey.pem");
  125. // map.put("publicKey", "/opt/wmproject/SBY-Secret/publickey.pem");
  126. // map.put("privateKey", "/opt/wmproject/SBY-Secret/privatekey.pem");
  127. map.put("publicKey", "/excel/publickey.pem");
  128. map.put("privateKey", "/excel/privatekey.pem");
  129. }
  130. if (osName.indexOf("mac") != -1){
  131. map.put("publicKey", "/Users/jimmy/Developer/repos/cert/taxhelpor/publickey.pem");
  132. map.put("privateKey", "/Users/xuqiqi/IdeaProjects/logos/dzdk-api-gateway/privatekey.pem");
  133. }
  134. if (osName.indexOf("windows") != -1) {
  135. // 开发测试
  136. map.put("publicKey", "D:/publickey.pem");
  137. map.put("privateKey", "D:/常用文本文件/代征代扣/封装接口资料/开发测试环境密钥/privatekey.pem");
  138. // // 生产
  139. // map.put("publicKey", "D:/常用文本文件/代征代扣/封装接口资料/生产环境密钥/publickey.pem");
  140. // map.put("privateKey", "D:/常用文本文件/代征代扣/封装接口资料/生产环境密钥/privatekey.pem");
  141. }
  142. return map;
  143. }
  144. }