接口鉴权V4

2023.03.01 17:14:47

    在使用接口服务之前,需要从【易盾官网 - 智能风控 - 服务管理】页面下获取 secretId 和 secretKey (请妥善保管此信息,避免泄漏),用于计算接口请求的认证签名。

    生成签名参数 signature

    在使用接口服务之前,需要生成用于校验身份合法性的签名参数 signature,生成方法如下:

    1. 对公有参数和部分私有参数,但不包括 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两个私有参数参与计算)

    2. 将排序好的参数名参数值对,拼装成字符串,格式为:key1value1key2value2…。根据上面示例结果为:bar2baz4foo1foobar3;

    3. 将安全凭证的secretKey,加到上一步拼装的参数字符串之后;

    4. 把 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)
    
    在线咨询 电话咨询:95163223 免费试用