package thyyxxk.simzfeeoprnsystm.utils.rxsign; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.Iterator; import java.util.Map; import org.bouncycastle.util.encoders.Hex; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import thyyxxk.simzfeeoprnsystm.utils.StringUtil; public class HseEncAndDecUtil { // 电子处方正式环境 private final static String chnlId = "2863D5752ED541EAAB5EFAAD6E8738D7"; private final static String sm4key = "C5284B71E4444204B07A03AD84F943E3"; private final static String prvKey = "Ext2wUfq/reXazwvUjN8n3sKiievMXXwEJ1ng//HxeI="; private final static String pubKey = "BN98Es/bSG2Si2gDtkS/uxNosr6l/aNr9D4Ui2OTU3A4sltrMhO/ThjYlKpBbuqqrXn0M6271sa6pFjcpvSjxyU="; /** * sm2签名 * @param message 未加密报文 * @return 签名串 String * @throws Exception */ public static String signature(String message){ byte[] messageByte; try { JSONObject jsonObject = JSON.parseObject(message); removeEmpty(jsonObject); messageByte = SignUtil.getSignText(jsonObject, sm4key).getBytes(StandardCharsets.UTF_8); }catch (Exception e){ messageByte = message.getBytes(); } byte[] chnlSecretByte = sm4key.getBytes(); byte[] prvkey = Base64.getDecoder().decode(prvKey); return Base64.getEncoder().encodeToString(EasyGmUtils.signSm3WithSm2(messageByte, chnlSecretByte, prvkey)); } /** * sm2验签 * @param msg sm4解密后报文 * @param source 原始响应报文 * @param signData 签名串 * @return 验证是否通过 boolean * @throws Exception */ public static boolean verify(String msg,String source, String signData){ byte[] msgByte; try { JSONObject jsonObject = JSON.parseObject(msg); JSONObject jsonObjects = JSON.parseObject(source); jsonObjects.remove("signData"); jsonObjects.remove("encData"); jsonObjects.put("data",jsonObject); removeEmpty(jsonObject); String str = SignUtil.getSignText(jsonObjects, sm4key); msgByte = str.getBytes(StandardCharsets.UTF_8); }catch (Exception e){ msgByte = msg.getBytes(); } byte[] signatureByte = Base64.getDecoder().decode(signData), chnlSecretByte = sm4key.getBytes(), pubKeyByte = Base64.getDecoder().decode(pubKey); return EasyGmUtils.verifySm3WithSm2(msgByte, chnlSecretByte, signatureByte, pubKeyByte); } /** * sm4加密 * @param message 待加密报文 * @return 加密后的报文内容 String * @throws Exception */ public static String sm4Encrypt(String message) throws Exception { //用appId加密appSecret获取新秘钥 byte[] appSecretEncData = EasyGmUtils.sm4Encrypt(chnlId.substring(0, 16).getBytes("UTF-8"), sm4key.getBytes("UTF-8")); //新秘钥串 byte[] secKey = Hex.toHexString(appSecretEncData).toUpperCase().substring(0, 16).getBytes("UTF-8"); //加密数据 return Hex.toHexString(EasyGmUtils.sm4Encrypt(secKey, message.getBytes("UTF-8"))).toUpperCase(); } /** * sm4解密 * @param message 待解密报文 * @return 解密后的报文 String * @throws Exception */ public static String sm4Decrypt (String message) throws Exception{ //生产解密key byte[] appSecretEncDataDecode = EasyGmUtils.sm4Encrypt(chnlId.substring(0, 16).getBytes("UTF-8"), sm4key.getBytes("UTF-8")); byte[] secKeyDecode = Hex.toHexString(appSecretEncDataDecode).toUpperCase().substring(0, 16).getBytes("UTF-8"); return new String(EasyGmUtils.sm4Decrypt(secKeyDecode, Hex.decode(message))); } private final static String version = "1.0.0"; private final static String encType = "sm4"; private final static String signType = "sm2"; /** * 创建请求报文 * @param encData 加密的报文 * @param signData 签名的报文 * @return */ public static JSONObject buildMsg(String encData,String signData){ JSONObject jsonObject = new JSONObject(); jsonObject.put("appId",chnlId); jsonObject.put("encData",encData); jsonObject.put("encType",encType); jsonObject.put("signData",signData); jsonObject.put("signType",signType); jsonObject.put("timestamp", System.currentTimeMillis()); jsonObject.put("version",version); return jsonObject; } /** * 创建和加密请求报文 * @param body 原始未加密的请求报文体 * @return * @throws Exception */ public static JSONObject encryptMsg(JSONObject body) throws Exception { JSONObject jsonObject = new JSONObject(); jsonObject.put("appId", chnlId); jsonObject.put("version",version); jsonObject.put("timestamp", System.currentTimeMillis()); jsonObject.put("encType",encType); jsonObject.put("data",body); jsonObject.put("signType",signType); // jsonObject.put("transType",transType); //加密后的报文 String encData = sm4Encrypt(body.toJSONString()); //签名 String signData = signature(jsonObject.toJSONString()); jsonObject.fluentRemove("data"); jsonObject.put("encData",encData); jsonObject.put("signData",signData); return jsonObject; } /** * 解密报文 * @param jsonObject 医保电子凭证响应的原始加密报文 * @return * @throws Exception */ public static JSONObject decryptMsg(JSONObject jsonObject) throws Exception { String msg = jsonObject.getString("encData"); String message = jsonObject.getString("message"); Integer code = jsonObject.getInteger("code"); if (null == code || code != 0){ throw new RuntimeException(message); } //解密 String msgS = sm4Decrypt(msg); return JSONObject.parseObject(msgS); } /** * 移除json中空值的键值对 * @param jsonObject */ private static void removeEmpty(JSONObject jsonObject){ Iterator> it = jsonObject.entrySet().iterator(); while (it.hasNext()){ Map.Entry entry = it.next(); Object value = entry.getValue(); if (value instanceof JSONArray) { JSONArray jsonArray = (JSONArray) value; // 数组长度为0时将其处理,防止Gson转换异常 if (jsonArray.isEmpty()) { it.remove(); } else { for (Object o : jsonArray) { JSONObject asJsonObject = (JSONObject) o; removeEmpty(asJsonObject); } } } if (value instanceof JSONObject) { JSONObject asJsonObject = (JSONObject) value; removeEmpty(asJsonObject); } if (value == null){ it.remove(); } if (value instanceof String && StringUtil.isEmpty(value)){ it.remove(); } } } }