签名生成说明
以如下请求为例,来说明signature的生成步骤:
1. 将以”w”作为前缀所有参数按key进行字典升序排列,将排序后的key,value字符串以%s=%s格式拼接起来。如下:
_w_appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxappid_w_param2=example.doc_w_param1=1000
请开发者关注:只有以”w”作为前缀才需要签名,否则容易导致签名不能通过验证。
2. 将appsecret加到最后,得到最终加密的字符串。如下:
_w_appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxappid_w_param1=example.doc_w_param2=1000_w_secretkey=xxxxxxxxxxxxxxxxxxxxxxxsecretkey其中xxxxxxxxxxxxxxxxxxxxxxxxxxxappid为实际申请的appid,xxxxxxxxxxxxxxxxxxxxxxxsecretkey为实际申请的appsecret。
3. 生成签名值
使用HMAC-SHA1哈希算法,使用注册的appsecret密钥对上一步骤的源字符串进行加密。(注:一般程序语言中会内置HMAC-SHA1加密算法的函数,例如PHP5.1.2之后的版本可直接调用hash_hmac函数。)
4. 然后将加密后的字符串经过Base64编码。 (注:一般程序语言中会内置Base64编码函数,例如PHP中可直接调用 base64_encode() 函数。)
5. 得到的签名值结果如下:
tBnhFqvVrC1LcJKye1m7GjzvqoA=
6. 将上面生成的字符串进行URL编码。
请开发者关注:URL编码注意事项,否则容易导致后面签名不能通过验证。
例如:
tBnhFqvVrC1LcJKye1m7GjzvqoA%3D
经过以上步骤后,即生成示例中的signature。JAVA示例代码:
//签名方法
import org.apache.commons.codec.digest.HmacUtils;
import java.util.*;
import static org.apache.commons.codec.binary.Base64.encodeBase64String;
public class Main {
private static String getSignature(Map<String, String> params, String appId, String appSecret) {
List<String> keys=new ArrayList();
for (Map.Entry<String, String> entry : params.entrySet()) {
keys.add(entry.getKey());
}
// 将所有参数按key的升序排序
Collections.sort(keys, new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
// 构造签名的源字符串
StringBuilder contents=new StringBuilder("");
for (String key : keys) {
if (key=="_w_signature"){
continue;
}
contents.append(key+"=").append(params.get(key));
System.out.println("key:"+key+",value:"+params.get(key));
}
contents.append("_w_secretkey=").append(appSecret);
System.out.println(appSecret);
System.out.println(contents.toString());
// 进行hmac sha1 签名
byte[] bytes= HmacUtils.
hmacSha1(appSecret.getBytes(),contents.toString().getBytes());
//字符串经过Base64编码
String sign= encodeBase64String(bytes);
System.out.println(sign);
return sign;
}
public static Map<String, String> paramToMap(String paramStr) {
String[] params = paramStr.split("&");
Map<String, String> resMap = new HashMap<String, String>();
for (int i = 0; i < params.length; i++) {
String[] param = params[i].split("=");
if (param.length >= 2) {
String key = param[0];
String value = param[1];
for (int j = 2; j < param.length; j++) {
value += "=" + param[j];
}
resMap.put(key, value);
}
}
return resMap;
}
}