公共签名

系统级 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", "~");
}

构造待签名的请求串:

  1. 把排序后的参数顺序拼接成如下格式:

    * 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);
}

参数说明:

  1. appSecret:你的appKey对应的秘钥appSecret

  2. stringToSign:即第三步生成的待签名请求串

5. 增加签名结果到请求参数中,发送请求

说明: 签名也要做特殊URL编码。

String signature = specialUrlEncode(sign);

Last updated

Was this helpful?