公共签名
系统级 Header
【必选】X-Sy-Key:AppKey
【必选】X-Sy-Signature:签名字符串
【必选】X-Sy-Timestamp:API调用者传递时间戳,值为当前时间的秒数,也就是从1970年1月1日起至今的时间转换为秒,时间戳有效时间为15分钟。
【必选】X-Sy-Nonce:API调用者生成的 UUID,结合时间戳防重放。
请求签名
对于每一次HTTP或者HTTPS协议请求,我们会根据访问中的签名信息验证访问请求者身份。具体由使用appKey和appSecret对称加密验证实现。其中appKey是访问者身份,appSecret是加密签名字符串和服务器端验证签名字符串的密钥,必须严格保密谨防泄露。
1. 指定请求参数
在代码中指定请求参数,参数中需要包含系统级Header和接口必备的参数信息。
说明: 请求参数中不允许出现以signature为key的参数。
示例代码如下:
String appKey = "testKsy";
String appSecret = "testSecret";
String timestamp = String.valueOf(System.currentTimeMillis()/1000);
String signNonce = java.util.UUID.randomUUID().toString().replaceAll("-", "");
java.util.Map<String, String> paras = new java.util.HashMap<String, String>();指定参数:
paras.put("appKey", testKey);
paras.put("timestamp", timestamp);
paras.put("signNonce", signNonce);
paras.put("name", "okok");
paras.put("mobile", "0999999999");
paras.put("credential_no", "1111581111");去除签名关键字Key:
if (paras.containsKey("signature"))
paras.remove("signature");2. 根据参数Key排序(升序)
参考代码如下:
java.util.TreeMap<String, String> sortParas = new java.util.TreeMap<String, String>(paras);3. 构造待签名的请求串
在一般的URLEncode后再增加三种字符替换:加号(+)替换成 %20、星号(*)替换成 %2A、%7E 替换回波浪号(~)参考代码如下:
public static String specialUrlEncode(String value) throws Exception {
return java.net.URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
}构造待签名的请求串:
把排序后的参数顺序拼接成如下格式:
* specialUrlEncode(参数Key) + "=" + specialUrlEncode(参数值)参考代码如下:
java.util.Iterator<String> it = sortParas.keySet().iterator(); StringBuilder sortQueryString = new StringBuilder(); while (it.hasNext()) { String key = it.next(); sortQueryString.append("&").append(specialUrlEncode(key)).append("=").append(specialUrlEncode(paras.get(key))); } String sortedQueryString = sortQueryString.substring(1); //去除第一个多余的&符号
4. 签名
签名采用HmacSHA1算法 + Base64,编码采用UTF-8。参考代码如下:
String sign = sign(appSecret, sortedQueryString);
public static String sign(String appSecret, String stringToSign) throws Exception {
javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
mac.init(new javax.crypto.spec.SecretKeySpec(appSecret.getBytes("UTF-8"), "HmacSHA1"));
byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
return new sun.misc.BASE64Encoder().encode(signData);
}参数说明:
appSecret:你的appKey对应的秘钥appSecretstringToSign:即第三步生成的待签名请求串
5. 增加签名结果到请求参数中,发送请求
说明: 签名也要做特殊URL编码。
String signature = specialUrlEncode(sign);Last updated
Was this helpful?