签名机制步骤
sig的生成步骤,也就是auth签名校验算法如下:
Step 1. 构造源串:
第1步:将除“sig”外的所有参数按key进行字典升序排列。 包括头部的时间戳x-hmac-auth-date
第2步:将第1步中排序后的参数(key=value)用&拼接起来,并进行URL编码。请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。源串构造示例如下:
1.原始请求信息:
头部:x-hmac-auth-signature = 123456:at1Kzj3H9sZH4OGi3KNcZUy2VM4=x-hmac-auth-date = 1400461465910
HTTP请求方式:GET/POST
请求参数,例如:name=张三&idCard=320502198008082233
2.下面开始构造源串:
第1步:将除“sig”外的所有参数按key进行字典升序排列,排列结果为:idCard,name还有头部的时间戳:x-hmac-auth-date
第2步:将第1步中排序后的参数(key=value)用&拼接起来: idCard=320502198008082233& name=张三&x-hmac-auth-date =1400461465910&然后进行URL编码( 编码时请关注URL编码注意事项,否则容易导致后面签名不能通过验证),编码结果为:idCard%3D320502198008082233%26name%3D%E5%BC%A0%E4%B8%89%26x-hmac-auth-date%3D1400461465910
Step 2. 构造密钥:
Appid和Appkey都是由服务平台分配的在secretKey末尾加上一个字节的<font color=red>“&”</font>,例如:28bf094169a40a3bd188ba37ebe8723&
step 3. 生成签名值:
1.使用HMAC-SHA1加密算法,使用Step2中得到的密钥对Step1中得到的源串加密。
2.将加密后的字符串经过Base64编码得到的签名值结果如下,例如:at1Kzj3H9sZH4OGi3KNcZUy2VM4=
附(java语言签名核心代码):
public static String getSig(String appkey, String requestTimeString,
Map<String, String> parameter) {
try {
String kvString = "";
parameter.put("x-hmac-auth-date", requestTimeString);
System.out.println("x-hmac-auth-date ==>" + requestTimeString);
Set listKeys = parameter.keySet();
int length = listKeys.size();
Iterator it = listKeys.iterator();
List list = new ArrayList();
while (it.hasNext()) {
list.add(it.next());
}
Collections.sort(list);
for (int i = 0; i < length; i++) {
String key = (String) list.get(i);
if (i == length - 1)
kvString = kvString + key + "=" + parameter.get(key);
else {
kvString = kvString + key + "=" + parameter.get(key) + "&";
}
}
String kvStringE = URLEncoder.encode(kvString, "UTF-8");
kvString = kvStringE.replace("*", "%2A").replace("+", "%20");
System.out.println("keys升序排列处理 ==>" + kvString);
String firstStep = kvString;
String secretoauthkey = appkey;
secretoauthkey = secretoauthkey + "&";
System.out.println("构造密钥 ==>" + secretoauthkey);
String sig = "";
byte[] encryption = null;
try {
encryption = HMACSHA1.getSignature(firstStep, secretoauthkey);
sig = encodeBase64WithoutLinefeed(encryption);
} catch (Exception e) {
logger.error("", e);
}
System.out.println("生成签名值 sig ==>" + sig);
return sig;
} catch (Exception e) {
logger.error("", e);
}
return "";
}
private static String encodeBase64WithoutLinefeed(byte[] result) {
return Base64.encodeBase64String(result).trim();
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
public class HMACSHA1 {
private static final String HMAC_SHA1 = "HmacSHA1";
/**
* 生成签名数据
*
* @param data
* 待加密的数据
* @param key
* 加密使用的key
* @throws NoSuchAlgorithmException
*/
public static byte[] getSignature(String data, String key) throws Exception {
byte[] keyBytes = key.getBytes();
SecretKeySpec signingKey = new SecretKeySpec(keyBytes, HMAC_SHA1);
Mac mac = Mac.getInstance(HMAC_SHA1);
mac.init(signingKey);
return mac.doFinal(data.getBytes());
}
private HMACSHA1() {
}
}