文档中心 > 综合交通-商家对接

奇门签名算法

更新时间:2023/06/26 访问次数:64993

一、签名算法


如果您使用的是SDK,则生成签名对您来说是透明的。

签名算法如下,另外可以使用控制台的运维工具-签名辅助工具来协助您完成签名算法。


/**
     * 
     * 
     * @param params
     *            所有字符型的TOP请求参数(这个是除了sign以外的所有字段)
     * @param body
     *            请求主体内容
     * @param secret
     *            签名密钥
     * @param signMethod
     *            签名方法,目前支持:空(老md5)、md5, hmac_md5三种
     * @return 签名
     */
    public static String signTopRequest(Map<String, String> params, String body, String secret, String signMethod)
            throws IOException {
        // 第一步:检查参数是否已经排序
        String[] keys = params.keySet().toArray(new String[0]);
        Arrays.sort(keys);
        // 第二步:把所有参数名和参数值串在一起
        StringBuilder query = new StringBuilder();
        if (Constants.SIGN_METHOD_MD5.equals(signMethod)) {
            query.append(secret);
        }
        for (String key : keys) {
            String value = params.get(key);
            if (StringUtils.areNotEmpty(key, value)) {
                query.append(key).append(value);
            }
        }
        // 第三步:把请求主体拼接在参数后面
        if (body != null) {
            query.append(body);
        }
        // 第四步:使用MD5/HMAC加密
        byte[] bytes;
        if (Constants.SIGN_METHOD_HMAC.equals(signMethod)) {
            bytes = encryptHMAC(query.toString(), secret);
        } else if (Constants.SIGN_METHOD_HMAC_SHA256.equals(signMethod)) {
            bytes = encryptHMACSHA256(query.toString(), secret);
        }  else {
            query.append(secret);
            bytes = encryptMD5(query.toString());
        }
        // 第五步:把二进制转化为大写的十六进制
        return byte2hex(bytes);
    }

二、SDK验签使用说明


为了防止接口被人乱掉用,需要在服务端做验签的逻辑,校验请求的合法性。开发者要求使用验签算法来对请求合法性进行校验。服务端验签可以使用sdk提供的工具类SpiUtils,验签失败时候返回“验签失败回应示例”的内容即可,验签逻辑如下。SDK提供有java,c#,php,C,NodeJS版本,如果您不使用SDK,可以把该工具类拷贝到工程中;如果您使用的语言没有对应的SDK版本,可以参考附录的验签算法翻译成对应的语言。


/**
* 使用该方法同时请务必要阅读该方法的源码,大致了解该方法的实现。
*
* 如果验签失败则需要返回验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功;
* 
* 如果正确的请求老是误认为验签错误了,则确认以下几点:
* 1编码是否UTF8 
* 2密钥是否写错了,特别是沙箱和线上密钥别搞错
* 3request如果是json,xml类型(form不用理会)则确认inputstream是否被读取过了?如果需要使用body但不想改动麻烦,可以先执行验签,
* 然后在验签结果中获取body(checkResult.getRequestBody()方法)来执行业务逻辑
* 4上层框架是否有做封装导致参数变更
* 如果名以上几点检查没问题,请提供加签前的最终字符串给小二协助排查
*/
CheckResult result = SpiUtils.checkSign(request, targetAppSecret);  //这里执行验签逻辑
if(!result.isSuccess()) {  //如果验签失败则需要返回 验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功
//按验签失败回应示例
}



FAQ

关于此文档暂时还没有FAQ
返回
顶部