开发过程中,我们经常会与接口打交道,有的时候是调取别人网站的接口,有的 时候是为他人提供自己网站的接口,但是在这调取的过程中都离不开签名验证。
提示:以下是本篇文章正文内容,下面案例可供参考
是为了防止发送的信息被串改,发送方通过将一些字段要素按一定的规则排序后,在转化成json字符串,通过MD5加密机制发送,当接收方接受到请求后需要验证该信息是否被篡改过,也需要将对应的字段按照同样的规则生成验签sign,然后在于接收到的进行比对,可以发现信息是否被串改过。
可变性:每次的签名必须是不一样的。
时效性:每次请求的时效,过期作废等。
唯一性:每次的签名是唯一的。
完整性:能够对传入数据进行验证,防止篡改。
第 1 步: 将所有参数(注意是所有参数),除去 sign 本身,以及值是空的参数, 按参数名字母升序排序。
第 2 步: 然后把排序后的参数按参数 1 值 1 参数 2 值 2…参数 n 值 n(这里的参 数和值必须是传输参数的原始值,不能是经过处理的,如不能将"转成”后再拼接) 的方式拼接成一个字符串。
第 3 步: 把分配给接入方的验证密钥 key 拼接在第 2 步得到的字符串前面。
第 4步: 在上一步得到的字符串前面加上验证密钥 key(这里的密钥 key 是接口提供方分配给接口接入方的),然后计算 md5 值,得到 32 位字符串,然后转成大 写.
第 5 步: 计算第 3 步字符串的 md5 值(32 位),然后转成大写,得到的字符串作为 sign 的值。
着急的小伙伴开始催代码了
举例:
假设传输的数据是
/interface.php?sigin=sign_value&p2=v2&p1=v1&method=cancel&p3=&pn=v(实际情况最好是通过 post 方式发送), 其中 sign 参数对应的 sign_value 就是签名的值。
第一步,拼接字符串,首先去除 sign 参数本身,然后去除值是空的参数 p3,剩 下p2=v2&p1=v1&method=cancel& amp;pn=vn,然后按参数名字符升序排序, method=cancel&p1=v1&p2=v2&pn=vn.
第二步,然后做参数名和值的拼接,最后得到 methodcancelp1v1p2v2pnvn
第三步,在上面拼接得到的字符串前加上验证密钥 key,我们假设是 abc,得到 新的字符串 abcmethodcancelp1v1p2v2pnvn
第四步,然后将这个字符串进行 md5 计算,假设得到的是 abcdef,然后转为大 写,得到 ABCDEF 这个值即为 sign 签名值。
你是要上天吗,代码呢???
注意,计算 md5 之前请确保接口与接入方的字符串编码一致,如统一使用 utf-8 编码或者 GBK 编码,如果编码方式不一致则计算出来的签名会校验失败。
根据前面描述的签名参数 sign 生成的方法规则,计算得到参数的签名值,和参 数中通知过来的 sign 对应的参数值进行对比,如果是一致的,那么就校验通过, 如果不一致,说明参数被修改过。
来了、来了,观众老爷们要的示例代码来了
// 设置一个公钥(key)和私钥(secret),公钥用于区分用户,私钥加密数据,不能 公开
$key = "c4ca4238a0b923820dcc509a6f75849b";
$secret = "28c8edde3d61a0411511d3b1866f0636";
// 待发送的数据包
$data = array(
'username' => '[email protected]',
'sex' => '1',
'age' => '16',
'addr' => 'guangzhou',
'key' => $key,
'timestamp' => time(),
);
// 获取 sign
function getSign(secret,secret, secret,data) {
// 对数组的值按 key 排序
ksort($data);// 生成 url 的形式
$params = http_build_query($data);// 生成 sign
$sign = md5($params . $secret);
return $sign;
}
// 发送的数据加上 sign
data['sign']=getSign(data['sign'] = getSign(data[′sign′]=getSign(secret, $data);
/**
* 后台验证 sign 是否合法
* @param [type] $secret [description]
* @param [type] $data [description]
* @return [type] [description]
*/
function verifySign(secret,secret, secret,data) {
// 验证参数中是否有签名
if (!isset($data['sign']) || !$data['sign']) {
echo '发送的数据签名不存在'; die();
}
if (!isset($data['timestamp']) || !$data['timestamp']) {
echo '发送的数据参数不合法'; die();
}
// 验证请求, 10 分钟失效
if (time() - $data['timestamp'] > 600) {
echo '验证失效, 请重新发送请求'; die();
}
$sign = $data['sign'];unset($data['sign']);
ksort($data); $params = http_build_query($data);
// $secret 是通过 key 在 api 的数据库中查询 得到
$sign2 = md5($params . $secret);
if ($sign == $sign2) {
die('验证通过');
} else {
die('请求不合法');
}
}
?>
以上就是接口签名的内容,感谢各位大佬的阅读、点赞、评论,希望可以帮助到你们。我是 敲码农的小Bug,我们下期见。