HseEncAndDecUtil.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. package thyyxxk.simzfeeoprnsystm.utils.rxsign;
  2. import java.nio.charset.StandardCharsets;
  3. import java.util.Base64;
  4. import java.util.Iterator;
  5. import java.util.Map;
  6. import org.bouncycastle.util.encoders.Hex;
  7. import com.alibaba.fastjson.JSON;
  8. import com.alibaba.fastjson.JSONArray;
  9. import com.alibaba.fastjson.JSONObject;
  10. import thyyxxk.simzfeeoprnsystm.utils.StringUtil;
  11. public class HseEncAndDecUtil {
  12. // 电子处方正式环境
  13. private final static String chnlId = "2863D5752ED541EAAB5EFAAD6E8738D7";
  14. private final static String sm4key = "C5284B71E4444204B07A03AD84F943E3";
  15. private final static String prvKey = "Ext2wUfq/reXazwvUjN8n3sKiievMXXwEJ1ng//HxeI=";
  16. private final static String pubKey = "BN98Es/bSG2Si2gDtkS/uxNosr6l/aNr9D4Ui2OTU3A4sltrMhO/ThjYlKpBbuqqrXn0M6271sa6pFjcpvSjxyU=";
  17. /**
  18. * sm2签名
  19. * @param message 未加密报文
  20. * @return 签名串 String
  21. * @throws Exception
  22. */
  23. public static String signature(String message){
  24. byte[] messageByte;
  25. try {
  26. JSONObject jsonObject = JSON.parseObject(message);
  27. removeEmpty(jsonObject);
  28. messageByte = SignUtil.getSignText(jsonObject, sm4key).getBytes(StandardCharsets.UTF_8);
  29. }catch (Exception e){
  30. messageByte = message.getBytes();
  31. }
  32. byte[] chnlSecretByte = sm4key.getBytes();
  33. byte[] prvkey = Base64.getDecoder().decode(prvKey);
  34. return Base64.getEncoder().encodeToString(EasyGmUtils.signSm3WithSm2(messageByte, chnlSecretByte, prvkey));
  35. }
  36. /**
  37. * sm2验签
  38. * @param msg sm4解密后报文
  39. * @param source 原始响应报文
  40. * @param signData 签名串
  41. * @return 验证是否通过 boolean
  42. * @throws Exception
  43. */
  44. public static boolean verify(String msg,String source, String signData){
  45. byte[] msgByte;
  46. try {
  47. JSONObject jsonObject = JSON.parseObject(msg);
  48. JSONObject jsonObjects = JSON.parseObject(source);
  49. jsonObjects.remove("signData");
  50. jsonObjects.remove("encData");
  51. jsonObjects.put("data",jsonObject);
  52. removeEmpty(jsonObject);
  53. String str = SignUtil.getSignText(jsonObjects, sm4key);
  54. msgByte = str.getBytes(StandardCharsets.UTF_8);
  55. }catch (Exception e){
  56. msgByte = msg.getBytes();
  57. }
  58. byte[] signatureByte = Base64.getDecoder().decode(signData),
  59. chnlSecretByte = sm4key.getBytes(),
  60. pubKeyByte = Base64.getDecoder().decode(pubKey);
  61. return EasyGmUtils.verifySm3WithSm2(msgByte, chnlSecretByte, signatureByte, pubKeyByte);
  62. }
  63. /**
  64. * sm4加密
  65. * @param message 待加密报文
  66. * @return 加密后的报文内容 String
  67. * @throws Exception
  68. */
  69. public static String sm4Encrypt(String message) throws Exception {
  70. //用appId加密appSecret获取新秘钥
  71. byte[] appSecretEncData = EasyGmUtils.sm4Encrypt(chnlId.substring(0, 16).getBytes("UTF-8"), sm4key.getBytes("UTF-8"));
  72. //新秘钥串
  73. byte[] secKey = Hex.toHexString(appSecretEncData).toUpperCase().substring(0, 16).getBytes("UTF-8");
  74. //加密数据
  75. return Hex.toHexString(EasyGmUtils.sm4Encrypt(secKey, message.getBytes("UTF-8"))).toUpperCase();
  76. }
  77. /**
  78. * sm4解密
  79. * @param message 待解密报文
  80. * @return 解密后的报文 String
  81. * @throws Exception
  82. */
  83. public static String sm4Decrypt (String message) throws Exception{
  84. //生产解密key
  85. byte[] appSecretEncDataDecode = EasyGmUtils.sm4Encrypt(chnlId.substring(0, 16).getBytes("UTF-8"), sm4key.getBytes("UTF-8"));
  86. byte[] secKeyDecode = Hex.toHexString(appSecretEncDataDecode).toUpperCase().substring(0, 16).getBytes("UTF-8");
  87. return new String(EasyGmUtils.sm4Decrypt(secKeyDecode, Hex.decode(message)));
  88. }
  89. private final static String version = "1.0.0";
  90. private final static String encType = "sm4";
  91. private final static String signType = "sm2";
  92. /**
  93. * 创建请求报文
  94. * @param encData 加密的报文
  95. * @param signData 签名的报文
  96. * @return
  97. */
  98. public static JSONObject buildMsg(String encData,String signData){
  99. JSONObject jsonObject = new JSONObject();
  100. jsonObject.put("appId",chnlId);
  101. jsonObject.put("encData",encData);
  102. jsonObject.put("encType",encType);
  103. jsonObject.put("signData",signData);
  104. jsonObject.put("signType",signType);
  105. jsonObject.put("timestamp", System.currentTimeMillis());
  106. jsonObject.put("version",version);
  107. return jsonObject;
  108. }
  109. /**
  110. * 创建和加密请求报文
  111. * @param body 原始未加密的请求报文体
  112. * @return
  113. * @throws Exception
  114. */
  115. public static JSONObject encryptMsg(JSONObject body) throws Exception {
  116. JSONObject jsonObject = new JSONObject();
  117. jsonObject.put("appId", chnlId);
  118. jsonObject.put("version",version);
  119. jsonObject.put("timestamp", System.currentTimeMillis());
  120. jsonObject.put("encType",encType);
  121. jsonObject.put("data",body);
  122. jsonObject.put("signType",signType);
  123. // jsonObject.put("transType",transType);
  124. //加密后的报文
  125. String encData = sm4Encrypt(body.toJSONString());
  126. //签名
  127. String signData = signature(jsonObject.toJSONString());
  128. jsonObject.fluentRemove("data");
  129. jsonObject.put("encData",encData);
  130. jsonObject.put("signData",signData);
  131. return jsonObject;
  132. }
  133. /**
  134. * 解密报文
  135. * @param jsonObject 医保电子凭证响应的原始加密报文
  136. * @return
  137. * @throws Exception
  138. */
  139. public static JSONObject decryptMsg(JSONObject jsonObject) throws Exception {
  140. String msg = jsonObject.getString("encData");
  141. String message = jsonObject.getString("message");
  142. Integer code = jsonObject.getInteger("code");
  143. if (null == code || code != 0){
  144. throw new RuntimeException(message);
  145. }
  146. //解密
  147. String msgS = sm4Decrypt(msg);
  148. return JSONObject.parseObject(msgS);
  149. }
  150. /**
  151. * 移除json中空值的键值对
  152. * @param jsonObject
  153. */
  154. private static void removeEmpty(JSONObject jsonObject){
  155. Iterator<Map.Entry<String, Object>> it = jsonObject.entrySet().iterator();
  156. while (it.hasNext()){
  157. Map.Entry<String, Object> entry = it.next();
  158. Object value = entry.getValue();
  159. if (value instanceof JSONArray) {
  160. JSONArray jsonArray = (JSONArray) value;
  161. // 数组长度为0时将其处理,防止Gson转换异常
  162. if (jsonArray.isEmpty()) {
  163. it.remove();
  164. } else {
  165. for (Object o : jsonArray) {
  166. JSONObject asJsonObject = (JSONObject) o;
  167. removeEmpty(asJsonObject);
  168. }
  169. }
  170. }
  171. if (value instanceof JSONObject) {
  172. JSONObject asJsonObject = (JSONObject) value;
  173. removeEmpty(asJsonObject);
  174. }
  175. if (value == null){
  176. it.remove();
  177. }
  178. if (value instanceof String && StringUtil.isEmpty(value)){
  179. it.remove();
  180. }
  181. }
  182. }
  183. }