签名算法

优质
小牛编辑
127浏览
2023-12-01

算法描述

  1. 生成签名的时候,将颁发的sign_key加入到传递的参数中,参与加密
  2. 传递的参数(包含sign_key)按照参数名升序排序,然后,以&形式连接(类似格式为a=xxx&b=xxx&c=xxx...),生成小写的md5串
  3. 生成sign后,sign和其他参数一起传递,对于中文在传递的过程中,需要进行urlencode,加密的时候不进行urlencode(如是以POST方法json格式传参不需要urlencode)
  4. sign_key不要参与参数传递,只参与生成sign
  5. 对于所有API的调用中用到的签名都可以用此工具测试。签名验证工具

算法实现

php版本

    //将$sign_key加入到$params数组中,并对数组根据键名升序排序
    $params['sign_key'] = $sign_key;
    ksort($params); //对数组(map)根据键名升序排序
    $str = '';

    foreach ($params as $k => $v) {
        if ('' == $str) {
            $str .= $k . '=' . trim($v);
        } else {
            $str .= '&' . $k . '=' . trim($v);
        }
    }
    $sign = md5($str); //此处md5值为小写的32个字符

java版本

    /**
     * params需要为LinkedHashMap(有序map) ,值为调用接口的参数,除sign外
     **/
    public String genSign(Map<String, String> params, String signKey) {
        //将sign_key添加进去
        params.put("sign_key", signKey);

        //用&符号连接每一个键值对
        String str = "";
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if ("" == str) {
                str += entry.getKey() + "=" + entry.getValue().trim();
            } else {
                str += "&" + entry.getKey() + "=" + entry.getValue().trim();
            }
        }
        //最好记录这个加密前的字符串,防止签名出错时进行排查,
        //eg:access_token=test_access_token&client_id=test_client_id&timestamp=1559736242507&sign_key=test_sign_key
        //System.out.println(str); 
        MessageDigest md = MessageDigest.getInstance("MD5");
        //对字符串进行加密
        md.update(str.getBytes());
        //获得加密后的数据
        String sign = md.digest();
        return sign;
    }

变量说明

变量名类型说明
$sign_keystring申请应用时分配的密钥(保密存储,不要作为参数传递)
$paramsarray调用api时要传递的所有参数组成的数组(参数名为键,参数值为元素值)