API 加密规则详解
最新更新时间:2021.09.15¶
巨量 API 会对每个访问请求进行身份验证,即每个请求都需要包含签名信息(sign参数)以验证请求者身份。 签名信息由安全凭证生成,安全凭证包括 业务号(trade_no) 和 API Key;每个业务都有对应的API Key(请到业务管理中具体业务中获取),API Key相当于调用API的密码,一定要严格保密谨防泄露。
重要提示
巨量Api的所有接口调用全部使用HTTPS加密传输,调用接口也使用加密签名验签来确保您的信息安全。
1. 加密演示¶
为演示方便,此处虚构一个业务编号和key,为的是方便演示,在使用的使用过程中,需要您使用自己的业务编号和key。下面演示动态代理提取10个代理IP,附带城市名称和剩余可用时长,以Json格式返回的参数示例
- trade_no(业务编号):
1483587531995538
- num(提取数量):
10
- city_name(城市名称):
1
- ip_remain(剩余可用时长):
1
- result_type(数据返回格式):
json
- key(业务密钥):
99064631962e4e838dac1143092f6112
1.1 参数排序¶
首先对所有请求参数按参数名的字典序( ASCII 码)升序排序。注意:
- 只按参数名进行排序,参数值保持对应即可,不参与比大小;
- 按 ASCII 码比大小,如 InstanceIds.2 要排在 InstanceIds.12 后面,不是按字母表,也不是按数值。用户可以借助编程语言中的相关排序函数来实现这一能,如 php 中的 ksort 函数。 上述示例参数的排序结果如下:
city_name=1&num=10&ip_remain=1&result_type=json&trade_no=1178311789392776
使用其它程序设计语言开发时,可对上面示例中的参数进行排序,得到的结果一致即可。
1.2 拼接签名原文字符串¶
此步骤生成签名原文字符串。 签名原文字符串由以下几个参数构成:
签名原文串的拼接规则为:
示例的拼接结果为:
city_name=1&num=10&ip_remain=1&result_type=json&trade_no=1178311789392776&key=99064631962e4e838dac1143092f6112
1.3 生成加密字符串¶
此步骤生成签名串。使用 MD5
算法对上一步中获得的签名原文字符串进行签名,即可获得最终的签名串。
具体代码如下,以 PHP 语言为例:
<?php
$rawStr = 'city_name=1&ip_remain=1&num=10&result_type=json&trade_no=1178311789392776&key=99064631962e4e838dac1143092f6112';
echo md5($rawStr);
最终得到的签名串为:
MD5 使用32位小写格式
8f35c3e56bf640cb2597ea2492ca62db
1.4 生成Api链接示例¶
此处以动态代理提取IP的接口为例。
- 接口地址:http://v2.api.juliangip.com/dynamic/getips
- 请求字符串:city_name=1&num=10&ip_remain=1&result_type=json&trade_no=1178311789392776&sign=73fabf914b46cf91a0cce9e8e471b2a6
最后输出的链接为:
http://v2.api.juliangip.com/dynamic/getips?city_name=1&num=10&ip_remain=1&result_type=json&trade_no=1178311789392776&sign=73fabf914b46cf91a0cce9e8e471b2a6
2. 代码示例¶
提示
PHP生成请求字符串示例
- 在下面的示例中,不同编程语言,甚至同一语言每次执行得到的 url 可能都有所不同,表现为参数的顺序不同,但这并不影响正确性。只要所有参数都在,且签名计算正确即可。
- 其他语言示例请参考
<?php
class SignKit {
protected static $postCharset = "UTF-8";
protected static $fileCharset = "UTF-8";
/**
* MD5 加密
* @param $params
* @param $secret
* @return string
*/
public static function md5Sign($params,$secret): string
{
return md5(self::getSignContent($params) . '&key=' . $secret);
}
protected static function getSignContent($params): string
{
unset($params['sign']); // 删除Sign
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === self::checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = self::character($v, self::$postCharset);
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
/**
* 转换字符集编码
* @param $data
* @param $targetCharset
* @return string
*/
protected static function character($data, $targetCharset): string
{
if (!empty($data)) {
$fileType = self::$fileCharset;
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset);
}
}
return $data;
}
/**
* 校验$value是否非空
* if not set ,return true;
* if is null , return true;
**/
protected static function checkEmpty($value): bool
{
if (!isset($value))
return true;
if (trim($value) === "")
return true;
return false;
}
}
// 下面为生成示例
$key = "99064631962e4e838dac1143092f6112";
$rawStr = [
'trade_no' => '1483587531995538',
'num' => 10,
'city_name' => 1,
'remain' => 1,
'result_type' => 'json',
];
$sign = SignKit::md5Sign($params, $key);
echo http_build_query($params)."&sign=".$sign;