签名规则
兑吧与开发者之间进行接口交互请求,都会包含签名参数,链接中签名参数的生成,都是通过MD5生成的签名参数,以确保请求安全。
1.MD5签名原理
兑吧签名md5签名原理如下:
将请求参数和appSecret封装成Map集合,按照参数名(Key)进行升序排列,将排序后Map集合的参数值(value)拼装成字符串进行MD5签名。其中appSecret在签名中的顺序取决于他在所有参数名中的顺序。
例:appKey:testappkey , appSecret:testsecret
请求参数:{appKey=testappkey,type=virtual,timestamp=1405495206727}
添加appSecret之后的参数列表:{appKey=testappkey,type=virtual,timestamp=1405495206727,appSecret=testsecret}
按照Key升序排列之后,将参数值拼装字符串如下
签名原串:testappkeytestsecret1405495206727virtual
对上述字符串进行MD5:5fdfb6e31c6cb4b4de1a778286aa085b
签名url示例:https://activity.m.duiba.com.cn/gaw/supply/querySpuPage?appKey=testappkey×tamp=129832323&sign=39e73663eb1caf2096968e680991ba2c
注意
1.签名验证时,必须遍历request请求中的所有参数进行签名验证。
2.兑吧向开发者发起的请求,未来有可能会添加业务参数,开发者在验证请求时,务必对所有参数进行遍历,全部加入签名验证数据中。
3.签名过程中,参数值为空的参数不参与签名。
签名工具
Java签名工具代码
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.*;
public class SignTool {
public static boolean signVerify(String appSecret,HttpServletRequest request){
Map<String, String[]> map=request.getParameterMap();
Map<String, String> data=new HashMap<String, String>();
for(String key:map.keySet()){
data.put(key, map.get(key)[0]);
}
return signVerify(appSecret, data);
}
public static boolean signVerify(String appSecret,Map<String, String> params){
Map<String, String> map=new HashMap<String, String>();
map.put("appSecret", appSecret);
map.remove("formid");
for(String key:params.keySet()){
if(!key.equals("sign")){
map.put(key, params.get(key));
}
}
String sign=sign(map);
if(sign.equals(params.get("sign"))){
return true;
}
return false;
}
private static String toHexValue(byte[] messageDigest) {
if (messageDigest == null)
return "";
StringBuilder hexValue = new StringBuilder();
for (byte aMessageDigest : messageDigest) {
int val = 0xFF & aMessageDigest;
if (val < 16) {
hexValue.append("0");
}
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}
/**
*
* @param params
* @return
*/
public static String sign(Map<String,String> params){
List<String> keys=new ArrayList<String>(params.keySet());
Collections.sort(keys);
String string="";
for(String s:keys){
string+=params.get(s);
}
String sign="";
System.out.println(string);
try {
sign = toHexValue(encryptMD5(string.getBytes(Charset.forName("utf-8"))));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("md5 error");
}
System.out.println("sign="+sign);
return sign;
}
public static String signStrs(String strs){
String sign = null;
try {
sign = toHexValue(encryptMD5(strs.getBytes(Charset.forName("utf-8"))));
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("md5 error");
}
return sign;
}
private static byte[] encryptMD5(byte[] data)throws Exception{
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(data);
return md5.digest();
}
public static String signstring(Map<String, String> params){
List<String> keys=new ArrayList<String>(params.keySet());
Collections.sort(keys);
String str="";
for(String s:keys){
str+=params.get(s);
}
return str;
}
}