注意
验证签名是否正确,使用和demo一样参数计算出的sig和demo sig对比一致即可(所有参数都需要参与sig计算)
计算方法
测试环境:
appkey:61000158
secret:0031186e-5cc6-45a6-a090-3e88ec220452
将所有参数(包括appkey、timestamp、ver、from这4个系统参数)按名称排序,由“参数”+“值”合并为字符串,字符串前后增加与appkey对应的secret一起md5,然后取前30位;
示例:
appkey=61000158
secret=0031186e-5cc6-45a6-a090-3e88ec220452
from=01012345
ver=3.4.2
获取周边空闲司机接口业务参数:udid=123456&longitude=116.476561&latitude=40.018707&gpsType=baidu
合并为
appkey61000158from01012345gpsTypebaidulatitude40.018707longitude116.476561timestamp2019-05-23 19:30:35udid123456ver3.4.2
计算签名(小写)
sig=md5(0031186e-5cc6-45a6-a090-3e88ec220452appkey61000158from01012345gpsTypebaidulatitude40.018707longitude116.476561timestamp2019-05-23 19:30:35udid123456ver3.4.20031186e-5cc6-45a6-a090-3e88ec220452).subString(0,30)
sig=6aa9dd942ba4160819fb750517295d
md5在线加密网站:https://www.cmd5.com/ ,合作方可以将md5之前的字符串在该网站md5加密一下,看合作方md5加密的结果和该网站的加密结果是否相同,不相同的话则md5算法有问题。
@org.junit.Test
public void testIdleList() {
Map<String, String> treeMap = new TreeMap<>();
treeMap.put("appkey", "61000158");
treeMap.put("gpsType", "baidu");
treeMap.put("longitude", "116.476561");
treeMap.put("latitude", "40.018707");
treeMap.put("udid", "123456");
treeMap.put("timestamp", "2019-05-23 19:30:35");
treeMap.put("ver", "3.4.2");
treeMap.put("from", "01012345");
StringBuilder sb = new StringBuilder();
for (String key : treeMap.keySet()) {
String value = treeMap.get(key);
if (!key.equals("gpsstring") && !key.equals("callback") && !key.equals("_") && !key.equals("sig")) {
sb.append(key);
sb.append(value);
}
}
String sig = MD5Utils.md5("0031186e-5cc6-45a6-a090-3e88ec220452" + sb.toString() + "0031186e-5cc6-45a6-a090-3e88ec220452").substring(0,30);
treeMap.put("sig", sig);
RestTemplate restTemplate = new RestTemplate();
try {
UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://open.d.api.edaijia.cn/driver/idle/list?appkey={appkey}" +
"&from={from}&longitude={longitude}&gpsType={gpsType}&latitude={latitude}&udid={udid}×tamp={timestamp}&ver={ver}&sig={sig}").build().expand(treeMap).encode();
URI uri = uriComponents.toUri();
String s = restTemplate.getForObject(uri, String.class);
System.out.println(s);
} catch (RestClientException e) {
e.printStackTrace();
}
}
md5 方法
public class MD5Utils {
private static final char[] HEX_DIGITS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
public MD5Utils() {
}
private static String toHexString(byte[] b) {
StringBuilder sb = new StringBuilder(b.length * 2);
for (int i = 0; i < b.length; ++i) {
sb.append(HEX_DIGITS[(b[i] & 240) >>> 4]);
sb.append(HEX_DIGITS[b[i] & 15]);
}
return sb.toString();
}
public static String md5(String str) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(str.getBytes());
byte[] messageDigest = digest.digest();
return toHexString(messageDigest);
} catch (NoSuchAlgorithmException var3) {
var3.printStackTrace();
return "";
}
}
public static void main(String[] args) {
System.out.println(md5("abc"));
}
}
计算签名类
package cn.edaijia.nuggets.api.third.web.util;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
@Component
public class EdjSignUtils {
/**
* 生成签名的方法
* @param params 本次请求的所有参数都放在此map中
* @param secret e代驾分配的SECRET
* @return
*/
public static String generateSig(Map<String, String> params, String secret) {
List<Map.Entry<String, String>> paramsList = sort(params);
String queryStr = createQueryStr(paramsList);
String mdStr = secret + queryStr + secret;
String sig = md5(mdStr).substring(0, 30);
return sig;
}
private static List<Map.Entry<String, String>> sort(Map<String, String> params) {
List<Map.Entry<String, String>> paramsList =
new ArrayList<Map.Entry<String, String>>(params.entrySet());
Collections.sort(paramsList, new Comparator<Map.Entry<String, String>>() {
@Override
public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
return (o1.getKey()).toString().compareTo(o2.getKey());
}
});
return paramsList;
}
private static String createQueryStr(List<Map.Entry<String, String>> params) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.size(); i++) {
String key = params.get(i).getKey();
String value = params.get(i).getValue();
if (!key.equals("gpsstring") && !key.equals("callback") && !key.equals("_") && !key.equals("sig")) {
//参数 key=null 的情况下
if (StringUtils.isBlank(value)) {
sb.append(key);
} else {
sb.append(key);
sb.append(value);
}
}
}
return sb.toString();
}
/**
* @param plainText 明文
* @return 32位密文
*/
public static String md5(String plainText) {
String re_md5 = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plainText.getBytes());
byte b[] = md.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0) {
i += 256;
}
if (i < 16) {
buf.append("0");
}
buf.append(Integer.toHexString(i));
}
re_md5 = buf.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return re_md5;
}
}