签名认证

曹操与服务器供应商之间进行服务调用时需要根据申请client_id时生成的sign_key,对请求参数进行SHA1签名,并将参数名带入请求参数中。

曹操接受到请求后使用sign_key重新计算参数签名进行比较是否被篡改。

签名

使用API接口时,传递的所有参数都参与签名

使用H5接口时,部分参数参与签名,具体在第5章文档的参数内详述

签名方法:

1.生成签名时将sign_key加入传递的参数,参与签名;
2.将所有的参数按照key值按字符升序排列(key1value1key2value2),生成小写的签名作为sign;
3.生成sign后,sign与其他的参数一同传递;
4.sign_key不参与传递;
5.timestamp时间戳为毫秒,例如 timestamp=1508240915308

生成的签名可以在您创建的沙箱应用内的「签名验证」页进行验证。签名方式正确,是后续对接的基础

签名算法伪代码示例

PHP示例

    //PHP示例
    function createSign($data, $sign_key)
    {
        $data['sign_key'] = $sign_key;
        ksort($data);
        $sign = '';
        foreach ($data as $k => $v) {
            $sign .= $k;
            $sign .= $v;
        }
        $sign = sha1($sign);
        return $sign;
    }

JAVA示例

    //Java示例
    @Override
    public String sign(Map<String, Object> params, String signKey) throws Exception {
        params.put(SIGN_KEY, signKey);
        Map<String, String> needVerify = new HashMap<>();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            needVerify.put(entry.getKey(), String.valueOf(entry.getValue()));
        }
        List<Map.Entry<String, String>> entryList = new ArrayList<>(needVerify.entrySet());
        //排序
        Collections.sort(entryList, (o1, o2) -> o1.getKey().compareTo(o2.getKey()));
        StringBuilder buffer = new StringBuilder();
        for (Map.Entry<String, String> entry : entryList) {
            buffer.append(entry.getKey()).append(entry.getValue());
        }
        logger.info("sha1 签名参数:{}", buffer.toString());
        return SHA.encodeBySHA(buffer.toString());
    }