JAVA代码示例
verifySignature 方法
public Application verifySignature(OpenApiRequest openApiRequest) {
long nowExpires = Instant.now().getEpochSecond();
if (Math.abs(nowExpires - Integer.parseInt(openApiRequest.getExpires())) > 60 * 30) {
throw new OpenApiServiceException(openApiRequest, ErrorTypeEnum.EXCEED_TIME_LIMIT);
}
Application application = applicationService.getByAppId(openApiRequest.getAppId());
if (ObjectUtil.isEmpty(application) || !Objects.equals(application.getStatus(), DefaultStatusEnum.YES.getValue())) {
throw new OpenApiServiceException(openApiRequest, ErrorTypeEnum.DEVICE_APPID_INVALID);
}
if (OpenApiSignUtils.isErrorSign(openApiRequest.getData(), openApiRequest.getSign(), AESUtil.decrypt(application.getAppSecret()))) {
throw new OpenApiServiceException(openApiRequest, ErrorTypeEnum.DEVICE_SIGN_ERROR);
}
return application;
}OpenApiSignUtils 工具类
package com.deviceIot.common.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.apache.commons.codec.digest.DigestUtils;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
/**
* 开放接口签名工具类
*
*/
public class OpenApiSignUtils {
/**
* 私有化构造器(单例模式)
*/
private OpenApiSignUtils() {
}
// region 私有方法
/**
* 生成签名串
*
* @param data 请求参数
* @param appSecret appSecret
* @return 签名串
*/
private static String generateSignReduce(String data, String appSecret) {
return generateSignReduce(data) + "&key=" + appSecret;
}
/**
* 生成签名字符串
*
* @param data 生成签名的参数
* @return 签名字符串
*/
private static String generateSignReduce(String data) {
if (ObjectUtil.isEmpty(data)) {
return "";
}
JSONObject parse = JSONUtil.parseObj(data);
if (ObjectUtil.isEmpty(parse)) {
return "";
}
handleValue(parse);
return sortedCollectSign(parse);
}
// endregion
// region 工具方法
/**
* 生成签名 (MD5)
*
* @param data 请求参数
* @param appSecret appSecret
* @return 签名
*/
public static String generateSign(String data, String appSecret) {
return DigestUtils.md5Hex(generateSignReduce(data, appSecret)).toLowerCase();
}
/**
* 验证签名
*
* @param data 请求参数
* @param sign 签名
* @param appSecret appSecret
* @return 签名是否错误
*/
public static boolean isErrorSign(String data, String sign, String appSecret) {
return !generateSign(data, appSecret).equalsIgnoreCase(sign);
}
/**
* 对Json对象的value进行排序,如果value为对象时,先将对象转换成json字符串
* @param jsonObject Json对象
*/
public static void handleValue(JSONObject jsonObject) {
for (String key : jsonObject.keySet()) {
Object value = jsonObject.get(key);
if (ObjectUtil.isNotEmpty(value)) {
if (value instanceof JSONObject || value instanceof JSONArray) {
jsonObject.set(key, JSONUtil.toJsonStr(value));
}
}
}
}
/**
* 排序并生成签名字符串
* @param parse json对象
* @return 签名字符串
*/
public static String sortedCollectSign(JSONObject parse){
return parse.keySet().stream()
.filter(key -> !"sign".equalsIgnoreCase(key))
.filter(key -> ObjectUtil.isNotEmpty(parse.getStr(key)))
.sorted()
.map(key -> {
try {
return key + "=" + URLEncoder.encode(parse.getStr(key), StandardCharsets.UTF_8.name());
} catch (Exception e) {
return "";
}
})
.filter(ObjectUtil::isNotEmpty)
.collect(Collectors.joining("&"));
}
// endregion
}作者:yrh 创建时间:2026-06-05 14:29
最后编辑:yrh 更新时间:2026-06-05 14:43
最后编辑:yrh 更新时间:2026-06-05 14:43