You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
6.3 KiB
178 lines
6.3 KiB
3 years ago
|
/*
|
||
|
* Copyright (C), 2015-2019
|
||
|
* FileName: FuncUtils
|
||
|
* Author: xx
|
||
|
* Date: 2019/8/22 15:05
|
||
|
* Description: FuncUtils
|
||
|
* History:
|
||
|
* <author> <time> <version> <desc>
|
||
|
*/
|
||
|
package com.fr.plugin.tabledataservice.utils;
|
||
|
|
||
|
import cn.hutool.core.date.DateUtil;
|
||
|
import cn.hutool.core.util.IdUtil;
|
||
|
import cn.hutool.core.util.RandomUtil;
|
||
|
import cn.hutool.crypto.Mode;
|
||
|
import cn.hutool.crypto.Padding;
|
||
|
import cn.hutool.crypto.asymmetric.KeyType;
|
||
|
import cn.hutool.crypto.asymmetric.SM2;
|
||
|
import cn.hutool.crypto.symmetric.SM4;
|
||
|
import com.fanruan.api.json.JSONKit;
|
||
|
import com.fr.base.Icon;
|
||
|
import com.fr.base.IconManager;
|
||
|
import com.fr.data.NetworkHelper;
|
||
|
import com.fr.general.ComparatorUtils;
|
||
|
import com.fr.general.IOUtils;
|
||
|
import com.fr.io.utils.MD5Calculator;
|
||
|
import com.fr.json.JSONObject;
|
||
|
import com.fr.locale.InterProviderFactory;
|
||
|
import com.fr.plugin.tabledataservice.ConfigTableDataService;
|
||
|
import com.fr.web.utils.WebUtils;
|
||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||
|
|
||
|
import javax.servlet.http.HttpServletRequest;
|
||
|
import javax.servlet.http.HttpServletResponse;
|
||
|
import java.io.BufferedReader;
|
||
|
import java.io.IOException;
|
||
|
import java.io.InputStreamReader;
|
||
|
import java.nio.charset.StandardCharsets;
|
||
|
import java.security.Security;
|
||
|
import java.util.*;
|
||
|
|
||
|
import static com.fr.plugin.tabledataservice.Constants.ICON_PATH;
|
||
|
|
||
|
/**
|
||
|
* 〈Function Description〉<br>
|
||
|
* 〈FuncUtils〉
|
||
|
*
|
||
|
* @author xx
|
||
|
* @since 1.0.0
|
||
|
*/
|
||
|
public class FuncUtils {
|
||
|
|
||
|
static {
|
||
|
//如果是PKCS7Padding填充方式,则必须加上下面这行
|
||
|
Security.addProvider(new BouncyCastleProvider());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 数据加密和签名
|
||
|
*
|
||
|
* @param bizData 业务数据
|
||
|
* @param result
|
||
|
* @return
|
||
|
*/
|
||
|
public static void encryptData(String bizData, JSONObject result) {
|
||
|
//弹性平台sm2公钥
|
||
|
String iqbPublicKey = ConfigTableDataService.getInstance().getIqbPublicKey();
|
||
|
//可视化sm2私钥
|
||
|
String visualPrivateKey = ConfigTableDataService.getInstance().getVisualPrivateKey();
|
||
|
//可视化appId
|
||
|
String appId = ConfigTableDataService.getInstance().getVisualAppId();
|
||
|
String aesPw = RandomUtil.randomString(16);//明文sm4key
|
||
|
String aesIv = RandomUtil.randomString(16); //sm4iv
|
||
|
|
||
|
//对请求参数 sm4加密
|
||
|
String encryptData = sm4Encrypt(bizData, aesPw, aesIv);
|
||
|
|
||
|
//对明文aesPw sm2加密
|
||
|
String key = sm2Encrypt(aesPw, iqbPublicKey);
|
||
|
|
||
|
//组装请求参数
|
||
|
HashMap<String, Object> encryptReqMap = new HashMap<>();
|
||
|
encryptReqMap.put("appId", appId);
|
||
|
encryptReqMap.put("time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
|
||
|
encryptReqMap.put("data", encryptData);
|
||
|
encryptReqMap.put("key", key);
|
||
|
encryptReqMap.put("iv", aesIv);
|
||
|
encryptReqMap.put("requestNo", IdUtil.getSnowflake(2, 1).nextIdStr() + IdUtil.getSnowflake(2, 1).nextIdStr());
|
||
|
|
||
|
//获取待签名请求参数并用可视化私钥签名
|
||
|
String waitSign = getSignContent(encryptReqMap);
|
||
|
String signature = sign(waitSign, visualPrivateKey);
|
||
|
|
||
|
//签名附加到请求参数
|
||
|
result.put("appId", encryptReqMap.get("appId"));
|
||
|
result.put("time", encryptReqMap.get("time"));
|
||
|
result.put("data", encryptReqMap.get("data"));
|
||
|
result.put("key", encryptReqMap.get("key"));
|
||
|
result.put("iv", encryptReqMap.get("iv"));
|
||
|
result.put("requestNo", encryptReqMap.get("requestNo"));
|
||
|
result.put("sign", signature);
|
||
|
}
|
||
|
|
||
|
//SM2非对称加密
|
||
|
private static String sm2Encrypt(String data, String publicKey) {
|
||
|
return new SM2(null, publicKey).encryptBase64(data, KeyType.PublicKey);
|
||
|
}
|
||
|
|
||
|
//SM4对称加密
|
||
|
private static String sm4Encrypt(String bizData, String key, String iv) {
|
||
|
return cn.hutool.core.codec.Base64.encode(new SM4(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes()).encrypt(bizData));
|
||
|
}
|
||
|
|
||
|
//获取待签名数据
|
||
|
private static String getSignContent(HashMap<String, Object> paramMap) {
|
||
|
paramMap.remove("sign");
|
||
|
Map<String, Object> stringObjectMap = sortMapByKey(paramMap);
|
||
|
return JSONKit.create(stringObjectMap).encode();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 根据map的key进行字典升序排序
|
||
|
*
|
||
|
* @param map
|
||
|
* @return map
|
||
|
*/
|
||
|
private static Map<String, Object> sortMapByKey(Map<String, Object> map) {
|
||
|
Map<String, Object> treemap = new TreeMap<>(map);
|
||
|
List<Map.Entry<String, Object>> list = new ArrayList<>(treemap.entrySet());
|
||
|
list.sort(Map.Entry.comparingByKey());
|
||
|
return treemap;
|
||
|
}
|
||
|
|
||
|
// 签名
|
||
|
private static String sign(String data, String privateKey) {
|
||
|
return cn.hutool.core.codec.Base64.encode(new SM2(privateKey, null).sign(data.getBytes(StandardCharsets.UTF_8)));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* MD5验证:key、报表路径、时间戳计算
|
||
|
*
|
||
|
* @param appKey
|
||
|
* @param params
|
||
|
* @return
|
||
|
*/
|
||
|
public static Boolean validateMD5(String appKey, JSONObject params) {
|
||
|
StringBuffer str = new StringBuffer();
|
||
|
str.append(appKey);
|
||
|
str.append(params.getString("report_path"));
|
||
|
str.append(params.getString("timestamp"));
|
||
|
String token = MD5Calculator.calculateMD5(str.toString().getBytes());
|
||
|
return ComparatorUtils.equals(token, params.getString("sign"));
|
||
|
}
|
||
|
|
||
|
public static void printErrorJSON(HttpServletResponse res, int code) throws Exception {
|
||
|
JSONObject errorJSON = JSONObject.create();
|
||
|
errorJSON.put("err_code", code)
|
||
|
.put("err_msg", InterProviderFactory.getProvider().getLocText("Plugin-tabledataservice_Error_" + code));
|
||
|
WebUtils.printAsJSON(res, errorJSON);
|
||
|
}
|
||
|
|
||
|
public static JSONObject getParams(HttpServletRequest req) throws IOException {
|
||
|
BufferedReader br = new BufferedReader(new InputStreamReader(NetworkHelper.getRequestInputStream(req), "utf-8"));
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
String temp;
|
||
|
while ((temp = br.readLine()) != null) {
|
||
|
sb.append(temp);
|
||
|
}
|
||
|
br.close();
|
||
|
return new JSONObject(sb.toString());
|
||
|
}
|
||
|
|
||
|
public static String loadIcon() {
|
||
|
Icon icon = new Icon("json", IOUtils.readImage(ICON_PATH));
|
||
|
IconManager.getIconManager().addIcon(icon, true);
|
||
|
return icon.getName();
|
||
|
}
|
||
|
}
|