签名加密
客户的账号资源是属于客户的财产,为了防止盗用,我们在此约定,传递的数据除定义的业务参数外,还需要统一增加签名验证参数,这是签名专属的安全字段:
名称 | 类型 | 定义 |
---|---|---|
appId | String | 在申请接入时,伯索平台给予的appId |
validBegin | Number | 请求开始生效起始时间的Unix Epoch 时间戳,单位秒 |
validTime | Number | 请求有效时间段,单位秒 |
signature | String | 需要计算得出的签名值,服务端会比对验证URL合法性 |
签名规则:签名过程是将业务参数以 参数名称=参数值 的形式按照 参数名称 的字⺟表升序排序,并⽤ & 拼接, 然后⽤ HMAC-sha1 签名并以 Hex 格式输出 signature 值,再把全部字母转为大写的 signature 和其他参数一起提交到开放平台。
JS示例代码
/*!----------演示签名代码------------- */
const crypto = require('crypto');
// 业务参数,根据接口文档中定义,自行生成填写
let businessParam = {"name":"test","phone":"1234567890"};
//平台分配给开发者的应用秘钥
let signKey = 'a_secret';
//在业务参数的基础上 补充签名参数
businessParam["validBegin"] = Date.now()/1000; // 当前时间
businessParam["validTime"] = 60; // 60秒内地址有效
// 业务参数和签名验证混合后排序
let afterSortParam = Object.keys(businessParam).sort();
let res = []
for (let key of afterSortParam) {
res.push(`${key}=${businessParam[key]}`);
}
// 排序后连接成字符串
let content = res.join("&");
// 使用分配的signKey来加密生成signature
let signature = crypto.createHmac('sha1', signKey).update(content).digest('hex').toUpperCase();
// 生成的签名串signature和原来参数一起,得到最终的接口参数对象,发送给开放平台
businessParam[signature] = signature;
console.log(signature)
PHP示例代码
<?php
/** 伯索签名函数 */
function plaso_sign($str, $key) {
$signature = "";
if (function_exists('hash_hmac')) {
$signature = hash_hmac("sha1", $str, $key, false);
} else {
$blocksize = 64;
$hashfunc = 'sha1';
if (strlen($key) > $blocksize) {
$key = pack('H*', $hashfunc($key));
}
$key = str_pad($key, $blocksize, chr(0x00));
$ipad = str_repeat(chr(0x36), $blocksize);
$opad = str_repeat(chr(0x5c), $blocksize);
$hmac = pack(
'H*', $hashfunc(
($key ^ $opad) . pack(
'H*', $hashfunc(
($key ^ $ipad) . $str
)
)
)
);
$signature = bin2hex($hmac);
}
return strtoupper($signature);
}
/** 此处参与签名的参数按照字⺟表升序排序 */
$strParam = "name=test测试&phone=1234567890&validBegin=1&validTime=60";
$signKey = "a_secret";
echo(plaso_sign( $strParam, $signKey));
?>
Python示例代码
#!/usr/bin/env python3.6
import hashlib
import hmac
import time
import math
# 签名方法
def plaso_sign(message, key):
# 签名的两个参数使用UTF-8转为字节
key = bytes(key, 'UTF-8')
message = bytes(message, 'UTF-8')
# 使用指定的Key和指定的算法sha1对message进行哈希
digester = hmac.new(key, message, hashlib.sha1)
# 用16进制输出
signature1 = digester.hexdigest()
# 根据签名要求转换为大写
return signature1.upper()
# 业务参数 接口中定义
businessParamDict = {"phone":"1234567890","name":"test测试"}
# 平台分配给开发者的应用秘钥,参与签名加密
signKey = 'a_secret'
# 在业务参数的基础上,补充签名有效期参数
businessParamDict["validTime"] = 60
businessParamDict["validBegin"] = math.floor(time.time())
# 按照Key值正序排列,然后使用&和=号连接成请求字符串,结果类似这样:“name=test测试&phone=1234567890&validBegin=1&validTime=60”
sortedStrParam = '&'.join([k+"="+str(businessParamDict[k]) for k in sorted(businessParamDict.keys())])
print(plaso_sign(sortedStrParam,signKey))
修改于 10 个月前