|
|
@@ -0,0 +1,182 @@
|
|
|
+package org.dromara.common.encrypt.core.guomi;
|
|
|
+
|
|
|
+import cn.hutool.core.codec.Base64;
|
|
|
+import cn.hutool.http.HttpRequest;
|
|
|
+import cn.hutool.http.HttpResponse;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.hnca.common.utils.HmacComputing;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import lombok.Data;
|
|
|
+import lombok.NoArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.encrypt.enumd.Constants;
|
|
|
+import org.dromara.common.encrypt.properties.GuomiProperties;
|
|
|
+import org.dromara.common.encrypt.utils.MapUtils;
|
|
|
+import org.dromara.common.encrypt.utils.SHA256Utils;
|
|
|
+import org.dromara.common.redis.utils.RedisUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
+import org.springframework.data.redis.core.ValueOperations;
|
|
|
+
|
|
|
+import java.time.Duration;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+import static org.dromara.common.encrypt.enumd.Constants.TOKEN_PREFIX;
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+@Data
|
|
|
+@NoArgsConstructor
|
|
|
+@AllArgsConstructor
|
|
|
+public class GuomiApi {
|
|
|
+
|
|
|
+ private GuomiProperties config;
|
|
|
+
|
|
|
+ public StringRedisTemplate redisTemplate;
|
|
|
+ //获取token 最好存入redis中缓存起来,其他接口调用前都要获取token
|
|
|
+ public String getToken(){
|
|
|
+ ValueOperations<String, String> operation = redisTemplate.opsForValue();
|
|
|
+ String cacheToken = operation.get(Constants.guomi_send_token);
|
|
|
+ if(StringUtils.isNotBlank(cacheToken)) return cacheToken;
|
|
|
+ String appid = config.getAppid();//密码平台
|
|
|
+ String secretKey = config.getSecretKey();//密码平台秘钥
|
|
|
+
|
|
|
+ String url = config.getBaseurl() + config.getTokenurl();
|
|
|
+
|
|
|
+ String paasid = config.getPaasid();//接入平台
|
|
|
+ String passtoken= config.getPasstoken();//接入平台密钥
|
|
|
+ long timeStamp1=new Date().getTime();
|
|
|
+ String SHAString = HmacComputing.getHmacSign((appid+timeStamp1+secretKey),"UTF-8",secretKey,"HmacSHA256");
|
|
|
+ String nonce = String.valueOf((int)(Math.random()*36));
|
|
|
+ JSONObject params=new JSONObject();
|
|
|
+ String headerTimeStamp = String.valueOf(Calendar.getInstance().getTimeInMillis()/1000);
|
|
|
+ String signature = SHA256Utils.getSHA256StrJava(headerTimeStamp+passtoken+nonce+headerTimeStamp);
|
|
|
+ params.put("appId",appid);
|
|
|
+ params.put("timeStamp",timeStamp1);
|
|
|
+ params.put("hmacStr",SHAString);
|
|
|
+ String body = JSON.toJSONString(params);
|
|
|
+ HttpRequest request = HttpRequest.post(url)
|
|
|
+ .header("Content-Type","application/json")
|
|
|
+ .header("X-Tif-Paasid",paasid)
|
|
|
+ .header("X-Tif-Nonce",nonce)
|
|
|
+ .header("X-Tif-Timestamp",headerTimeStamp)
|
|
|
+ .header("X-Tif-Signature",signature)
|
|
|
+ .body(body);
|
|
|
+ log.info("请求国密token:{}",request.toString());
|
|
|
+ HttpResponse result = request.execute();
|
|
|
+ log.info("请求国密token返回:{}", result.toString());
|
|
|
+ String resBody = result.body();
|
|
|
+ LinkedHashMap<String, Object> resultLinked = MapUtils.stringTransformMap(resBody);
|
|
|
+ Object code = resultLinked.get("code");
|
|
|
+ if(code !=null && StringUtils.equals("200",code.toString())){
|
|
|
+ Object data = resultLinked.get("data");
|
|
|
+ String token = TOKEN_PREFIX+data.toString();
|
|
|
+ //将token 存入redis中
|
|
|
+ redisTemplate.opsForValue().set(Constants.guomi_send_token,token, 3500, TimeUnit.DAYS);
|
|
|
+// RedisUtils.setCacheObject(Constants.guomi_send_token,token, Duration.ofDays(350));
|
|
|
+ return token;
|
|
|
+ }
|
|
|
+ log.error("国密请求token错误,返回body的信息:{}", resBody);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //sm4加密
|
|
|
+ public String encyptSm4(String originStr){
|
|
|
+ if(StringUtils.isBlank(originStr)) return null;
|
|
|
+ String token = getToken();
|
|
|
+ if(StringUtils.isBlank(token)) {
|
|
|
+ log.error("国密请求SM4加密接口错误,token为空");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ JSONObject params=new JSONObject();
|
|
|
+ params.put("keyIndex",config.getIndex());
|
|
|
+ params.put("plainText", Base64.encode(originStr.getBytes()));
|
|
|
+ params.put("algorithm", "SM4");
|
|
|
+ String body = JSON.toJSONString(params);
|
|
|
+
|
|
|
+ String paasid = config.getPaasid();//接入平台
|
|
|
+ String passtoken= config.getPasstoken();//接入平台密钥
|
|
|
+ String nonce = String.valueOf((int)(Math.random()*36));
|
|
|
+ String headerTimeStamp = String.valueOf(Calendar.getInstance().getTimeInMillis()/1000);
|
|
|
+ String signature = SHA256Utils.getSHA256StrJava(headerTimeStamp+passtoken+nonce+headerTimeStamp);
|
|
|
+
|
|
|
+ String url = config.getBaseurl() + config.getSm4encrypt();
|
|
|
+ HttpRequest request = HttpRequest.post(url)
|
|
|
+ .header("Content-Type","application/json")
|
|
|
+ .header("X-Tif-Paasid",paasid)
|
|
|
+ .header("X-Tif-Nonce",nonce)
|
|
|
+ .header("X-Tif-Timestamp",headerTimeStamp)
|
|
|
+ .header("X-Tif-Signature",signature)
|
|
|
+ .header("Authorization",token)
|
|
|
+ .body(body);
|
|
|
+
|
|
|
+ log.info("请求SM4加密接口-请求信息:{}",request.toString());
|
|
|
+ HttpResponse result = request.execute();
|
|
|
+ log.info("请求SM4加密接口-响应信息:{}",result.toString());
|
|
|
+
|
|
|
+ String resBody = result.body();
|
|
|
+ LinkedHashMap<String, Object> resultLinked = MapUtils.stringTransformMap(resBody);
|
|
|
+ Object code = resultLinked.get("code");
|
|
|
+ if(code !=null && StringUtils.equals("200",code.toString())){
|
|
|
+ LinkedHashMap<String, Object> res = (LinkedHashMap<String, Object>) resultLinked.get("data");
|
|
|
+ return (String)res.get("encryptedData");
|
|
|
+ }
|
|
|
+
|
|
|
+ log.error("国密请求SM4加密接口错误,返回body的信息:{}", resBody);
|
|
|
+
|
|
|
+ return originStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ //sm4解密
|
|
|
+ public String decyptSm4(String encyptString){
|
|
|
+ if(StringUtils.isBlank(encyptString)) return null;
|
|
|
+ String token = getToken();
|
|
|
+ if(StringUtils.isBlank(token)) {
|
|
|
+ log.error("国密请求SM4解密接口错误,token为空");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ JSONObject params=new JSONObject();
|
|
|
+ params.put("keyIndex",config.getIndex());
|
|
|
+ params.put("encryptedData",encyptString);
|
|
|
+ params.put("algorithm", "SM4");
|
|
|
+ String body = JSON.toJSONString(params);
|
|
|
+
|
|
|
+ String paasid = config.getPaasid();//接入平台
|
|
|
+ String passtoken= config.getPasstoken();//接入平台密钥
|
|
|
+ String nonce = String.valueOf((int)(Math.random()*36));
|
|
|
+ String headerTimeStamp = String.valueOf(Calendar.getInstance().getTimeInMillis()/1000);
|
|
|
+ String signature = SHA256Utils.getSHA256StrJava(headerTimeStamp+passtoken+nonce+headerTimeStamp);
|
|
|
+ String url = config.getBaseurl()+config.getSmt4decrypt();
|
|
|
+
|
|
|
+ HttpRequest request = HttpRequest.post(url)
|
|
|
+ .header("Content-Type","application/json")
|
|
|
+ .header("X-Tif-Paasid",paasid)
|
|
|
+ .header("X-Tif-Nonce",nonce)
|
|
|
+ .header("X-Tif-Timestamp",headerTimeStamp)
|
|
|
+ .header("X-Tif-Signature",signature)
|
|
|
+ .header("Authorization",token)
|
|
|
+ .body(body);
|
|
|
+
|
|
|
+ log.info("请求SM4解密接口-请求信息:{}",request.toString());
|
|
|
+ HttpResponse result = request.execute();
|
|
|
+ log.info("请求SM4解密接口-响应信息:{}",result.toString());
|
|
|
+
|
|
|
+ String resBody = result.body();
|
|
|
+ LinkedHashMap<String, Object> resultLinked = MapUtils.stringTransformMap(resBody);
|
|
|
+ Object code = resultLinked.get("code");
|
|
|
+ if(code !=null && StringUtils.equals("200",code.toString())){
|
|
|
+ LinkedHashMap<String, Object> res = (LinkedHashMap<String, Object>) resultLinked.get("data");
|
|
|
+ String plainText = (String)res.get("plainText");
|
|
|
+ return Base64.decodeStr(plainText);
|
|
|
+ }
|
|
|
+
|
|
|
+ log.error("国密请求SM4加密接口错误,返回body的信息:{}", resBody);
|
|
|
+
|
|
|
+ return encyptString;
|
|
|
+ }
|
|
|
+}
|