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.

152 lines
6.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.charge.util;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import javax.servlet.ServletOutputStream;
/**
* 签名工具
*
* @author keytop
* @date 2020/3/6
*/
public class SignUtils {
/**
* 功能判断一个字符串是不是JSON格式
*
* @param str
* @return
*/
public static boolean isJsonString(String str) {
if (str.indexOf("{") >= 0) return true;
if (str.indexOf("[") >= 0) return true;
return false;
}
/**
* 参数签名
* 示例:
* 参数对象:{"amount":100,"orderNo":"闽C12345","payTime":"2020-03-06 10:57:22","freeDetail":"[{\"code\":\"\",\"money\":100,\"time\":0,\"type\":0}]","paySource":"85d15350778b11e9bbaa506b4b2f6421","outOrderNo":"T20200306124536001","parkId":"1000001","payableAmount":200,"reqId":"5be4e3e6d5704a7d91ccbd9731d970f5","payType":1006,"payMethod":6,"appId":"85d15350778b11e9bbaa506b4b2f6421","freeTime":0,"paymentExt":"{\"deviceNo\":\"123456\"}","freeMoney":100,"ts":1583744086841}
* url拼接amount=100&freeDetail=[{"code":"","money":100,"time":0,"type":0}]&freeMoney=100&freeTime=0&orderNo=闽C12345&outOrderNo=T20200306124536001&parkId=1000001&payMethod=6&paySource=85d15350778b11e9bbaa506b4b2f6421&payTime=2020-03-06 10:57:22&payType=1006&payableAmount=200&paymentExt={"deviceNo":"123456"}&reqId=5be4e3e6d5704a7d91ccbd9731d970f5&ts=1583744086841&EED96C219E83450A
* 签名结果B19F7863ADCC8B5442A757AC7B90F6AC
*
* @param requestBody 参数对象
* @param appSecret 秘钥
* @return
*/
public static String paramsSign(JSONObject requestBody, String appSecret) {
TreeMap<String, String> params = new TreeMap<>();
for (String key : new ArrayList<>(requestBody.keySet())) {
// 假设我们要移除以 "age" 开头的属性
Object value = requestBody.get(key);
if (isJsonString(value.toString())) {
requestBody.remove(key);
}
}
//过滤掉keyappId字段空属性及Map或List等复杂对象
requestBody.entrySet().stream().filter(
p -> !"key".equals(p.getKey())
&& !"appId".equals(p.getKey())
&& p.getValue() != null
&& !(p.getValue() instanceof Map)
&& !(p.getValue() instanceof Iterable))
.forEach(p -> {
if (!p.getValue().equals("")) {
params.put(p.getKey(), p.getValue().toString());
}
});
//拼接appSecret
String temp = Joiner.on("&").withKeyValueSeparator("=").join(params).concat("&").concat(appSecret);
String MD5 = md5(temp).toUpperCase();
return MD5;
}
/**
* 功能:安快的闸机签名
*
* @param requestBody
* @param appSecret
* @return
*/
public static String paramsAnKuaiSign(JSONObject requestBody, String appSecret) {
TreeMap<String, String> params = new TreeMap<>();
requestBody.entrySet().stream().filter(
p -> p.getValue() != null
&& !(p.getValue() instanceof Map)
&& !(p.getValue() instanceof Iterable)
&& !(p.getValue() instanceof JSONObject)
&& !(p.getValue() instanceof JSONArray)
)
.forEach(p -> {
if (!p.getValue().equals("")) {
params.put(p.getKey(), p.getValue().toString());
}
});
//拼接appSecret
String temp = Joiner.on("&").withKeyValueSeparator("=").join(params).concat("&secret=").concat(appSecret);
String res = md5(temp);
return res;
}
/**
* 对文本执行 md5 摘要加密, 此算法与 mysql,JavaScript生成的md5摘要进行过一致性对比.
*
* @param plainText
* @return 返回值中的字母为小写
*/
private static String md5(String plainText) {
if (null == plainText) {
plainText = "";
}
String mD5Str = null;
try {
// JDK 支持以下6种消息摘要算法不区分大小写
// md5,sha(sha-1),md2,sha-256,sha-384,sha-512
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes(StandardCharsets.UTF_8));
byte[] b = md.digest();
int i;
StringBuilder builder = new StringBuilder(32);
for (byte value : b) {
i = value;
if (i < 0) {
i += 256;
}
if (i < 16) {
builder.append("0");
}
builder.append(Integer.toHexString(i));
}
mD5Str = builder.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return mD5Str;
}
public static void main(String[] args) {
String source = "{\"amount\":100,\"orderNo\":\"闽C12345\",\"payTime\":\"2020-03-06 10:57:22\",\"freeDetail\":\"[{\\\"code\\\":\\\"\\\",\\\"money\\\":100,\\\"time\\\":0,\\\"type\\\":0}]\",\"paySource\":\"EED96C219E83450A\",\"outOrderNo\":\"T20200306124536001\",\"parkId\":\"1000001\",\"payableAmount\":200,\"reqId\":\"748584ae47104b0ab239732767ddc679\",\"payType\":1006,\"payMethod\":6,\"appId\":\"EED96C219E83450A\",\"freeTime\":0,\"paymentExt\":\"{\\\"deviceNo\\\":\\\"123456\\\"}\",\"freeMoney\":100,\"ts\":1583464576264}";
JSONObject jo = JSONObject.parseObject(source);
String appSecret = "85d15350778b11e9bbaa506b4b2f6421";
System.out.println(paramsSign(jo, appSecret));
//4402E3F7DB94CCCF034F9AFA86F5F9CD
//4402E3F7DB94CCCF034F9AFA86F5F9CD
}
}