合作伙伴工作台
注册

签名算法

为了防止API调用过程中被黑客恶意篡改,调用任何一个API都需要携带签名,API网关服务端会根据请求参数,对签名进行验证,签名不合法的请求将会被拒绝。API网关目前只支持HAMC_SHA1签名算法,

签名大体过程如下:

①对API中定义的所有输入参数(注意签名字段必须包括API定义中的所有字段,如果某个字段不需要输入参数值,则使用0长度字符串代替参数值,并加入到签名字段列表中),根据参数名称的ASCII码表的顺序排序。如:

foo = 2

bar = 1

foo_bar = 3

foobar = null

排序后的顺序是

bar = 1

foo = 2

foo_bar = 3

foobar = null

②在上述输入参数的前面添加上公共参数中的application和timestamp(使用offset修正后)参数:

application = 10000.1234567

timestamp = 1519637736018

bar = 1

foo = 2

foo_bar = 3

foobar = null

③将排序好的参数名和参数值使用冒号按成对拼接后,再通过换行符将所有键值对连接在一起,根据上面的示例得到的字符串结果为:

application:10000.1234567

timestamp:1519637736018

bar:1

foo:2

foo_bar:3

foobar:

④对于HTTP BODY数据的签名通过二进制的方式追加到最后,参考下面的签名示例代码。

⑤把拼装好的字符串采用utf-8编码,使用签名算法对编码后的字节流进行HMAC_SHA1摘要计算。

⑥将摘要得到的字节流结果再使用Base64进行编码计算得到最后结果:

SeLSjSQezf/z1FqDmuQYsu9B/+g=

具体获取签名以及调用可以参考以下Java代码示例:

/**
* @param param    api 配置参数表
* @param timestamp UNIX格式时间戳
* @param application appKey,到应用管理打开应用可以找到此值
* @param secret 密钥,到应用管理打开应用可以找到此值
* @param body 请求body数据,如果是GET请求,此值写null
* @return 签名数据
*/
public static String sign(Map<String, String> param, long timestamp, String application, String secret, byte[] body) throws Exception {
   // 连接系统参数
   StringBuffer sb = new StringBuffer();
   sb.append("application").append(":").append(application).append("\n");
   sb.append("timestamp").append(":").append(timestamp).append("\n");
   // 连接请求参数
   if (param != null) {
       TreeSet<String> keys = new TreeSet<String>(param.keySet());
       Iterator<String> i = keys.iterator();
       while (i.hasNext()) {
           String s = i.next();
           String val = param.get(s);
           sb.append(s).append(":").append(val == null ? "" : val).append("\n");
       }
   }
   //body数据写入需要签名的字符流中
   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   baos.write(sb.toString().getBytes("utf-8"));
   if (body != null && body.length > 0) {
       baos.write(body);
       baos.write("\n".getBytes("utf-8"));
   }
   // 得到需要签名的字符串
   String string = baos.toString("utf-8");
   System.out.println("Sign string: " + string);
   // hmac-sha1编码
   byte[] bytes = null;
   SecretKey secretKey = new SecretKeySpec(secret.getBytes("utf-8"), "HmacSha1");
   Mac mac = Mac.getInstance(secretKey.getAlgorithm());
   mac.init(secretKey);
   bytes = mac.doFinal(string.getBytes("utf-8"));
   // base64编码
   String encryptedString = new String(Base64.encodeBase64(bytes));
   // 得到需要提交的signature签名数据
   return encryptedString;
}


这篇文档是否帮助您解决了问题?
如果您愿意进一步帮助我们改进文档 ,请留下您的联系方式。