接口鉴权V4
2023.03.01 17:14:47
在使用接口服务之前,需要从【易盾官网 - 智能风控 - 服务管理】页面下获取 secretId 和 secretKey (请妥善保管此信息,避免泄漏),用于计算接口请求的认证签名。
生成签名参数 signature
在使用接口服务之前,需要生成用于校验身份合法性的签名参数 signature,生成方法如下:
-
对公有参数和部分私有参数,但不包括 signature 参数,按照参数名ASCII码表升序顺序排序。如参数:foo=1, bar=2,foo_bar=3, baz=4 。排序后的顺序是 bar=2, baz=4, foo=1, foobar=3; (check在线检测接口还需加上token、ip两个私有参数进行参与计算)(getConfig接口需要加上ip、sdkData两个私有参数参与计算)
-
将排序好的参数名参数值对,拼装成字符串,格式为:key1value1key2value2…。根据上面示例结果为:bar2baz4foo1foobar3;
-
将安全凭证的secretKey,加到上一步拼装的参数字符串之后;
-
把 3 中的字符串,采用 UTF-8 编码,使用 MD5算法(128位长度)对字符串进行摘要计算,得到signature参数值(32位十六进制字符串)。
示例代码
详细签名方法见:https://github.com/yidun/irisk-openapi-demo/tree/v4
String signature = SignatureUtil.getSignature(secretKey, params);
其中 SignatureUtil.java 如下:
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.Map;
@Slf4j
public class SignatureUtil {
/**
* 签名方法,注意params的value不要为null(空字符串和null的区别),否则可能造成前后端签名不一致
*
* @param secretKey
* @param params
* @return
*/
public static String getSignature(String secretKey, Map<String, String> params) {
String signature = "";
if (StringUtils.isEmpty(secretKey) || ObjectUtils.isEmpty(params)) {
return signature;
}
try {
// 1. 参数名按照ASCII码表升序排序
String[] keys = params.keySet().toArray(new String[0]);
Arrays.sort(keys);
// 2. 按照排序拼接参数名与参数值
StringBuilder paramBuffer = new StringBuilder();
for (String key : keys) {
paramBuffer.append(key).append(params.get(key) == null ? "" : params.get(key));
}
// 3. 将secretKey拼接到最后
paramBuffer.append(secretKey);
// 4. MD5是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32个十六进制字符。
signature = DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8"));
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return signature;
}
}
/**
* 拼接组装参与计算的params参数示例
* 不同接口校验参数不同,详见目录下的demo文件: https://github.com/yidun/irisk-openapi-demo/tree/v4
*/
public Map<String,String> getParamsMap(){
Map<String, String> signMap = new HashMap<>(16);
// 公共参数
signMap.put("version", version);
signMap.put("secretId", secretId);
signMap.put("businessId", businessId);
signMap.put("timestamp", timestamp);
signMap.put("nonce", nonce);
// 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数
signMap.put("token", token);
signMap.put("ip", ip);
return signMap;
}
}
# 签名方法样例
def __init__(self, secret_id, secret_key, business_id, version):
"""
Args:
secret_id (str) 产品id,每个应用接入时,会分配secretId和私钥secretKey。
secret_key (str) 产品密钥,每个应用接入时,会分配secretId和私钥secretKey。
business_id (str) 每个业务接入时,均会分配业务 ID
version (str) 版本号,如400
"""
self.secret_id = secret_id
self.secret_key = secret_key
self.business_id = business_id
self.version = version
def gen_signature(self, params):
buff = ""
for k in sorted(params.keys()):
buff += str(k) + str(params[k])
buff += self.secret_key
return hashlib.md5(buff.encode("utf8")).hexdigest()
# 拼接组装参与计算的params参数示例
# 不同接口校验参数不同,详见目录下的demo文件: https://github.com/yidun/irisk-openapi-demo/tree/v4
def get_signature_params(self, params):
signature_params = {
# 公共参数
"secretId": params["secretId"],
"businessId": params["businessId"],
"nonce": params["nonce"],
"timestamp": params["timestamp"],
"version": params["version"],
# 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数
"token": params["token"],
"ip": params["ip"],
}
return signature_params
详细签名方法见:https://github.com/yidun/irisk-openapi-demo/tree/v4
/**
* 生成签名方法
* 不同openapi的签名参数不同
* @param $secretKey
* @param $params
* @return string
*/
function gen_signature($secretKey, $params){
ksort($params);
$buff="";
foreach($params as $key=>$value){
if($value !== null) {
$buff .=$key;
$buff .=$value;
}
}
$buff .= $secretKey;
return md5($buff);
}
/**
* 拼接组装参与计算的params参数示例
* 不同接口校验参数不同,详见目录下的demo文件: https://github.com/yidun/irisk-openapi-demo/tree/v4
*/
def get_signature_params(self, params):
signature_params = {
/** 公共参数 */
"secretId": params["secretId"],
"businessId": params["businessId"],
"nonce": params["nonce"],
"timestamp": params["timestamp"],
"version": params["version"],
/** 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数 */
"token": params["token"],
"ip": params["ip"],
}
return signature_params
详细签名方法见:https://github.com/yidun/irisk-openapi-demo/tree/v4
// 根据secretKey和parameters生成签名
public static String genSignature(String secretKey, Dictionary<String, String> parameters)
{
parameters = parameters.OrderBy(o => o.Key, StringComparer.Ordinal).ToDictionary(o => o.Key, p => p.Value);
StringBuilder builder = new StringBuilder();
foreach (KeyValuePair<String, String> kv in parameters)
{
builder.Append(kv.Key).Append(kv.Value);
}
builder.Append(secretKey);
String tmp = builder.ToString();
MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(Encoding.UTF8.GetBytes(tmp));
builder.Clear();
foreach (byte b in result)
{
builder.Append(b.ToString("x2").ToLower());
}
return builder.ToString();
}
/**
*
* 拼接组装参与计算的params参数示例
* 不同接口校验参数不同,详见目录下的demo文件:https://github.com/yidun/irisk-openapi-demo/tree/v4
*/
public Dictionary<String, String> getParamsMap(){
Dictionary<String, String> parameters = new Dictionary<String, String>();
// 公共参数
parameters.Add("version", version);
parameters.Add("secretId", secretId);
parameters.Add("businessId", businessId);
parameters.Add("timestamp", timestamp);
parameters.Add("nonce", nonce);
// 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数
parameters.Add("token", token);
parameters.Add("ip", ip);
return parameters;
}
详细签名方法见:https://github.com/yidun/irisk-openapi-demo/tree/v4
//生成签名算法--工具方法
var genSignature = function (secretKey, paramsJson) {
var sorter = function (paramsJson) {
var sortedJson = {};
var sortedKeys = Object.keys(paramsJson).sort();
for (var i = 0; i < sortedKeys.length; i++) {
sortedJson[sortedKeys[i]] = paramsJson[sortedKeys[i]]
}
return sortedJson;
}
var sortedParam = sorter(paramsJson);
var needSignatureStr = "";
for (var key in sortedParam) {
var value = sortedParam[key];
needSignatureStr = needSignatureStr + key + value;
}
needSignatureStr += secretKey;
signatureMethod = "md5";
return crypto.createHash(signatureMethod).update(needSignatureStr, "utf-8").digest("hex");
};
不同接口校验参数不同,详见目录下的demo文件:https://github.com/yidun/irisk-openapi-demo/tree/v4
// 拼接组装参与计算的params参数示例
var post_data = {
// 公共参数
secretId: secretId,
businessId: businessId,
version: version,
timestamp: timestamp,
nonce: nonce,
// 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数
token: token,
ip: ip,
}
// 生成签名信息
func genSignature(params map[string]interface{}) string {
var signatureParams map[string]string
signatureParams = make(map[string]string)
signatureParams["secretId"] = params["secretId"].(string)
signatureParams["businessId"] = params["businessId"].(string)
signatureParams["nonce"] = params["nonce"].(string)
signatureParams["version"] = params["version"].(string)
signatureParams["timestamp"] = params["timestamp"].(string)
signatureParams["ip"] = params["ip"].(string)
signatureParams["token"] = params["token"].(string)
var paramStr string
keys := make([]string, 0, len(signatureParams))
for k := range signatureParams {
keys = append(keys, k)
}
sort.Strings(keys)
for _, key := range keys {
paramStr += key + signatureParams[key]
}
paramStr += secretKey
md5Reader := md5.New()
md5Reader.Write([]byte(paramStr))
return hex.EncodeToString(md5Reader.Sum(nil))
}
// 不同接口校验参数不同,详见目录下的demo文件:https://github.com/yidun/irisk-openapi-demo/tree/v4
// 拼接组装参与计算的params参数示例
var signatureParams map[string]string
signatureParams = make(map[string]string)
// 公共参数
signatureParams["secretId"] = params["secretId"].(string)
signatureParams["businessId"] = params["businessId"].(string)
signatureParams["nonce"] = params["nonce"].(string)
signatureParams["version"] = params["version"].(string)
signatureParams["timestamp"] = params["timestamp"].(string)
// 私有参数,详见具体接口部分的描述。 示例:check在线检测接口还需加上如下私有参数
signatureParams["ip"] = params["ip"].(string)
signatureParams["token"] = params["token"].(string)