如果您使用的是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提供的工具类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()) { //如果验签失败则需要返回 验签失败的结果,并且需要和配置对应的上,系统才认为是验签成功 //按验签失败回应示例 }