签名生成说明

以如下请求为例,来说明signature的生成步骤:

https://wwo.wps.cn/office/w/1?_w_appid=xxxxxxxxxxxxxxxxxxxxxxxxxxxappid&_w_param1=1000&_w_param2=example.doc&_w_signature=tBnhFqvVrC1LcJKye1m7GjzvqoA%3D

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示例代码:

  1. //签名方法
  2. import org.apache.commons.codec.digest.HmacUtils;
  3. import java.util.*;
  4. import static org.apache.commons.codec.binary.Base64.encodeBase64String;
  5. public class Main {
  6. private static String getSignature(Map<String, String> params, String appId, String appSecret) {
  7. List<String> keys=new ArrayList();
  8. for (Map.Entry<String, String> entry : params.entrySet()) {
  9. keys.add(entry.getKey());
  10. }
  11. // 将所有参数按key的升序排序
  12. Collections.sort(keys, new Comparator<String>() {
  13. public int compare(String o1, String o2) {
  14. return o1.compareTo(o2);
  15. }
  16. });
  17. // 构造签名的源字符串
  18. StringBuilder contents=new StringBuilder("");
  19. for (String key : keys) {
  20. if (key=="_w_signature"){
  21. continue;
  22. }
  23. contents.append(key+"=").append(params.get(key));
  24. System.out.println("key:"+key+",value:"+params.get(key));
  25. }
  26. contents.append("_w_secretkey=").append(appSecret);
  27. System.out.println(appSecret);
  28. System.out.println(contents.toString());
  29. // 进行hmac sha1 签名
  30. byte[] bytes= HmacUtils.
  31. hmacSha1(appSecret.getBytes(),contents.toString().getBytes());
  32. //字符串经过Base64编码
  33. String sign= encodeBase64String(bytes);
  34. System.out.println(sign);
  35. return sign;
  36. }
  37. public static Map<String, String> paramToMap(String paramStr) {
  38. String[] params = paramStr.split("&");
  39. Map<String, String> resMap = new HashMap<String, String>();
  40. for (int i = 0; i < params.length; i++) {
  41. String[] param = params[i].split("=");
  42. if (param.length >= 2) {
  43. String key = param[0];
  44. String value = param[1];
  45. for (int j = 2; j < param.length; j++) {
  46. value += "=" + param[j];
  47. }
  48. resMap.put(key, value);
  49. }
  50. }
  51. return resMap;
  52. }
  53. }