设备指纹接入

接口通用参数

请求公共参数

易盾设备指纹服务的所有接口均包含这些公共参数。

参数名称类型必须最大长度描述
versionString4接口版本号,当前可用版本为200
secretIdString32秘钥id ,由营销反作弊服务分配
businessIdString32业务id,由营销反作弊服务分配
timestampLong10当前 UNIX 时间戳,单位:秒。
nonceString32随机字符串,与 timestamp 联合起来,用于防止重放攻击
signatureString32请求签名,用来验证此次请求的合法性。签名过程和算法参见:签名生成算法。请注意:请将签名转换成小写。

通用响应结果

所有接口响应均采用json格式,如无特殊说明,每次请求的返回值都包含如下字段:

参数名称类型描述
codeint接口调用状态,取值参见:响应返回码。
msgString结果说明,如果调用出错,返回错误描述
resultObject接口返回结果,具体参见各接口说明。

响应返回码

返回码返回码描述说明
200ok接口调用状态。
400bad request请求参数错误
401forbidden没权限使用此接口
405param error参数错误
410signature failure签名验证失败
420request expired请求时间戳不正确
430replay attack重放请求
440decode error参数解密失败
450wrong token查询token错误
503service unavailable服务器内部出现异常

接口鉴权

  • 申请安全凭证

在第一次使用 API 之前,需申请安全凭证,安全凭证包括 SecretId 和 SecretKey ,SecretId 是用于标识 API 调用者的身份,SecretKey 是用于加密签名字符串和服务器端验证签名字符串的密钥。SecretKey 必须严格保管,避免泄露。

  • 签名生成算法

签名过程:

  • 参数排序:对所有请求参数(不包括 signature 参数),按照参数名ASCII码表升序顺序排序。如:foo=1, bar=2, foo_bar=3, baz=4 排序后的顺序是 bar=2, baz=4, foo=1, foobar=3 。
  • 拼接参数:将排序好的参数名和参数值构造成字符串,格式为:key1+value1+key2+value2… 。根据上面的示例得到的构造结果为:bar2baz4foo1foobar3。
  • 拼接KEY:选择与 secretId 配对的 secretKey ,加到上一步构造好的参数字符串之后,如 secretKey=6308afb129ea00301bd7c79621d07591 ,则最后的参数字符串为 bar2baz4foo1foobar36308afb129ea00301bd7c79621d07591 。
  • 签名HASH:把上一步骤拼装好的字符串采用 utf-8 编码,使用 MD5 算法对字符串进行摘要,计算得到 signature 参数值,将其加入到接口请求参数中即可。MD5 是128位长度的摘要算法,用16进制表示,一个十六进制的字符能表示4个位,所以签名后的字符串长度固定为32位十六进制字符。

示例代码

/**
 * 生成签名信息
 * @param secretKey 产品私钥
 * @param params 接口请求参数名和参数值map,不包括signature参数名
 * @return
 */
public static String genSignature(String secretKey, Map<String, String> params) {
if (secretKey == null || params == null || params.size() == 0) {
    		return "";
    }
    // 1. 参数名按照ASCII码表升序排序
    String[] keys = params.keySet().toArray(new String[0]);
    Arrays.sort(keys);
    // 2. 按照排序拼接参数名与参数值
    StringBuffer paramBuffer = new StringBuffer();
    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个十六进制字符。
    return DigestUtils.md5Hex(paramBuffer.toString().getBytes("UTF-8"));
}

设备指纹check接口

  • 接口地址:https://ac.dun.163yun.com/v2/activity/check
  • 请求方法:POST
  • 接口说明:设备指纹检测
  • 注意事项:建议设置http请求的超时时间,且建议http超时的情况下,认为检测结果为 “正常”。

请求参数

公共参数已省略,详细见:请求公共参数,其他参数如下:

参数名称类型必须最大长度描述
tokenString256设备指纹结果查询token,由业务前端页面提交给业务后端。
accountString256用户唯一标识,如果是手机号or邮箱,支持传入hash值,hash算法:md5(account)
emailString64用户的邮箱,如果需要加密,支持传入hash值,hash算法:md5(email)
phoneString64默认国内手机号。如有海外手机,需包含国家地区代码,格式为”地区代码-手机号码“。如果需要加密,支持传入hash值,使用MD5算法对1开头,11位纯数字手机号进行加密后的值,32位小写,hash算法:md5(phone)
ipString20用户参加活动时的ip
extDataString2048额外信息,建议自己构造json结构

响应结果

  • 参数说明

响应字段如下,通用响应字段已省略,详细参见:通用响应结果。

参数名类型描述
actionint检测结果,取值如下:0 正常,10 嫌疑,20 致命
hitTypeint命中类型,取值如下:0:正常
taskIdString任务id,与检测请求一一对应,建议保存此值方便以后数据查询
detailjson设备信息详情,字段解释见设备指纹字段表
  • iOS/Android 返回字段
参数名描述终端
deviceId设备唯一指纹iOS、Android
osv系统版本iOS、Android
model手机厂商iOS、Android
appVersionAPP版本号iOS、Android
simulator是否模拟器iOS、Android
root是否rootiOS、Android
flag是否被调试iOS、Android
isInjection是否注入iOS、Android
macmac地址Android
  • web/h5 返回字段
参数名描述终端
deviceId设备唯一指纹web/h5
appVersion浏览器版本信息web/h5
  • 响应结果示例

设备指纹的响应结果:

{
    "code":200,
    "msg":"ok",
    "result":{
        	"action":0,
        	"hitType":0,
        	"taskId":"12345678900987654321123456789000",
        	"detail":{
        	    "deviceResult":1,
        	    "deviceInfo":{
        	        "deviceId":"xxx",
        	        ...
        	    }
        	}
    }
}

示例代码

public class ActivityProtectionChecker {

    /** 产品密钥ID,产品标识 */
    private static final String SECRET_ID = "your secret id";

    /** 产品私有密钥,服务端生成签名信息使用,请严格保管,避免泄露 */
    private static final String SECRET_KEY = "your secret key";

    /** 业务ID,易盾根据产品业务特点分配 */
    private static final String BUSINESS_ID = "your business id";

    /** 设备指纹检测接口地址 */
    private static final String API_URL = "https://ac.dun.163yun.com/v2/activity/check";

    /** 实例化HttpClient,发送http请求使用,可根据需要自行调参 */
    private static final HttpClient httpClient = HttpClient4Utils.createHttpClient(100, 20, 1000, 1000, 1000);

    public static void main(String[] args) throws Exception {

        String token = "9ca17ae2e6ffcda170e2e6ee95c13ba8888aa6ee4df2b3fe8af241f59d9e8dc15eb3bcafd9b84ba1ebacbaef2af0feaec3b92a87abafb2f64e82bfb995e65387ae00d0bc50ac9b9a91cd5cb8bda697fb72839bee9e";
        String account = "100002";
        String email = "zhangsanzuiniu@163.com";
        String phone = "18888888888";
        String ip = "127.0.0.1";
       

        Map<String, String> params = new HashMap<String, String>();
        params.put("version", "200");
        params.put("secretId", SECRET_ID);
        params.put("businessId", BUSINESS_ID);
        params.put("timestamp", System.currentTimeMillis() / 1000 + "");
        params.put("nonce", Math.random() + "");
        params.put("token", token);

        params.put("account", account);
        // 对邮箱取md5
        params.put("email", md5(email));
        // 对手机号取md5
        params.put("phone", md5(phone));
        params.put("ip", loginIp);
        params.put("extData","{}");

        // 生成签名,参见签名过程的示例代码
        params.put("signature", SignatureUtils.genSignature(SECRET_KEY, params));

        // 发送check请求,业务方可以选择自己熟悉的工具包发送请求
        // 请特别注意,调用接口时,请设置http超时时间
        // 建议http超时的情况下,认为识别结果为“正常”
        String response = HttpClient4Utils.sendPost(httpClient, API_URL, params, Consts.UTF_8);
        try {
            // 解析响应
            JsonObject jObject = new JsonParser()
.parse(response).getAsJsonObject();
            int code = jObject.get("code").getAsInt();
            String msg = jObject.get("msg").getAsString();
            if (code == 200) {
                JsonObject dataObject = jObject.getAsJsonObject("result");
                int action = dataObject.get("action").getAsInt();
                if (action == 0) {
                    System.out.println("正常");
                } else if (action == 10) {
                    System.out.println("嫌疑");
                } else if (action == 20) {
                    System.out.println("致命");
                }
                //获取具体的设备信息
                //JsonObject deviceObj = dataObject.getAsJsonObject("detail");
            } else {
                System.out.println(String.format("ERROR: code=%d, msg=%s", code, msg));
            }
        } catch (Exception e) {
            System.out.println("接口调用异常(超时 等),当作[正常]处理");

            e.printStackTrace();
        }
    }
}
QQ咨询:反馈更及时 在线咨询 电话咨询:95163223