集成要求
合规说明
请注意,在贵司的App中集成同盾提供的SDK产品时:
1.1 根据《网络安全法》《电信条例》《电信和互联网用户个人信息保护规定》等相关法律法规要求及监管实践中的标准,在贵司的最终用户首次启动App并在贵司开始采集信息之前,贵司应以交互界面或设计(如隐私政策弹窗等)向最终用户完整告知收集、使用、与第三方共享最终用户个人信息的目的、方式和范围,并征得最终用户的明示同意。
1.2 为向贵司提供业务安全和风控服务,同盾SDK将采集、处理、使用用户的手机终端唯一标志信息(IMEI/IDFA)、Android ID、OAID、IMSI、MEID、MAC 地址、SIM 卡序列号、设备序列号、设备类型、设备型号、系统类型、地理位置、登录 IP 地址等设备信息。为确保贵司使用相关服务的合规性,前述隐私政策应涵盖对同盾SDK提供服务并采集、处理、使用相关信息的授权,以下条款内容供贵司参考,具体表述可由贵司根据贵司隐私协议的整体框架和内容自行确定:
同盾SDK:为了业务安全和风控,我司使用了同盾 SDK,该 SDK 需要获取您的手机终端唯一标志信息(IMEI/IDFA)、Android ID、OAID、IMSI、MEID、MAC 地址、SIM卡序列号、设备序列号、设备类型、设备型号、系统类型、地理位置、登录 IP 地址、应用程序列表、运行中进程信息、传感器(光传感器、重力传感器、磁场传感器、加速度传感器、陀螺仪传感器、心率传感器)相关设备信息,用于设备欺诈风险识别。 |
同盾隐私协议:https://www.trustdecision.com/legal/privacy-policy
环境要求
条目 | 说明 |
---|---|
兼容版本 | 支持主流机型,Android 5.0及以上系统 |
支持架构 | armeabi-v7a, arm64-v8a |
集成步骤
集成SDK
添加仓库
首先, 请在项目根目录的 build.gradle
加入maven库的配置
allprojects {
repositories {
...
mavenCentral()
}
}
如果您的 Gradle 版本是 7 或更高版本,请将这些行添加到您的 settings.gradle
repositories {
...
mavenCentral()
}
添加依赖
在项目的 app/build.gradle
中加上依赖,如图:
dependencies {
// 设备安全组件
implementation 'com.trustdecision.android:mobrisk:4.3.2.8'
// 活体检测
implementation 'com.trustdecision.android:liveness:2.2.3'
}
如果遇到合规性问题,我们也可以在依赖阶段排除相关模块的采集,如下:
dependencies {
// 设备安全组件
implementation('com.trustdecision.android:mobrisk:4.3.2.8'){
// 移除后sdk不获取安装包列表
exclude group: 'com.trustdecision.android', module: 'packagelist'
// 移除后sdk不会收集READ_PHONE_STATE相关信息
exclude group: 'com.trustdecision.android', module: 'readphone'
// 移除后sdk不会收集地理位置相关信息
exclude group: 'com.trustdecision.android', module: 'location'
// 移除后sdk不会收集传感器相关信息
exclude group: 'com.trustdecision.android', module: 'sensor'
// 移除后sdk不会收集wifi相关信息
exclude group: 'com.trustdecision.android', module: 'wifiinfo'
}
}
ABI类型
SDK目前支持 armeabi-v7a、arm64-v8a 两种ABI类型,建议接入方在 app/build.gradle
文件内添加 abiFilters
配置选择所需要的架构类型,示例
defaultConfig {
........
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
具体架构,请以您自己需要支持的架构为准!
配置AndroidManifest.xml
在应⽤module下的 AndroidManifest.xml ⽂件中声明以下权限
<manifest>
<!--必选权限-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--如果您的应用是面向海外市场,在google play 上发布,请添加此项-->
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<!--以下权限是可选权限,不声明此部分权限将放弃部分设备信息的采集,对风险识别有一定影响-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!-- Android11及以上获取安装包列表需要该权限,采集安装包列表涉及到⻛险合规,是否需要该权限业务⽅⾃⾏选
择 -->
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
tools:ignore="QueryAllPackagesPermission" />
</manifest>
权限说明
权限 | 说明 |
---|---|
INTERNET(必选) | 允许程序访问网络连接,发送请求与服务器进行通信 |
ACCESS_NETWORK_STATE(必选) | 获取网络连接状态信息 |
ACCESS_WIFI_STATE(必选) | 获取当前WiFi接入的状态以及WLAN热点的信息 |
AD_ID(海外必选) | 获取google 广告ID |
ACCESS_COARSE_LOCATION | 获取粗略位置信息,精度大概误差在30~1500米 |
ACCESS_FINE_LOCATION | 获取精确位置信息,定位精度达10米以内 |
READ_PHONE_STATE | 读取SIM卡相关信息 |
QUERY_ALL_PACKAGES | 获取应用程序列表 |
SDK 的使用方法
注意事项
确保在用户同意隐私协议后,再进行SDK初始化,避免出现用户未同意隐私协议就进行SDK初始化采集,引发合规风险。
SDK配置
TD的sdk使用TDRisk.Builder方法对sdk初始参数进行配置设置,并将设置结果作为初始化参数提供给sdk初始化方法initWithOptions()使用。
TDRisk.Builder必须参数配置如下
配置 key | 定义 | 说明 | 示例代码 |
---|---|---|---|
partnerCode | 合作方编码 | 同盾的合作方编码,请联系同盾运营获取 | builder.partnerCode("partner") |
partnerKey | 合作方Key | 同盾的合作方Key,请联系同盾运营获取 | builder.partnerKey("partnerKey") |
appKey | 应用标识 | 应用标识,参考如何申请appKey | builder.appKey("appKey") |
country | 国家地区 | TDRisk.COUNTRY_US 北美 TDRisk.COUNTRY_FRA 欧洲 TDRisk.COUNTRY_SG 新加坡 TDRisk.COUNTRY_IDNA 印尼 | builder.country(TDRisk.COUNTRY_SG) |
initWithOptions方法选传参数,详情见附表(初始化配置可选参数列表)
最佳实践
- 在应用入口Application的onCreate方法中调用初始化并异步获取blackBox
// 应用入口APPlication的onCreate
TDRisk.Builder builder = new TDRisk.Builder()
/*************************** 必传 ***************************/
.partnerCode("demo") // 同盾的合作⽅编码,请填写⾃身的合作⽅编码
.partnerKey("key") // 同盾平台注册的合作方Key
.appKey("appKey") // 同盾平台注册的应用标识
.country(TDRisk.COUNTRY_CN); // 国家地区参数,列表可以参考下文全部配置说明
/*************************** 必传 ***************************/
if(⽤户同意隐私协议){
TDRisk.initWithOptions(getApplicationContext(), builder);
TDRisk.getBlackBox(new TDRiskCallback() {
@Override
public void onEvent(String blackbox) {
// 此处回调在新开辟的子线程
// ⽹络正常的情况下,会在1-2s内返回结果;⽹络异常的情况下,会在超时时间(默认最长15s)后返回
Log.i("TD", "init & get success");
}
});
}
- 在实际业务节点同步获取blackBox
// 比如注册的时候
public void register() {
...
String blackBox = TDRisk.getBlackBox();
...
}
状态检查
- 执行initWithOptions初始化成功会在 logcat中打印以下log:
TD_JAVA: Tongdun sdk load success
TD_JAVA: Tongdun sdk init success
- SDK上报数据成功,getBlackBox()返回的结果长度为26位字符串。如: rGPGX1678775227I9NCwcuVJCb。
- 异常情况下,getBlackBox()返回的结果长度可能达到5000字符,详情可查看正常blackBox和降级blackBox的差异
获取SDK版本号
示例代码
// 获取SDK版本号
TDRisk.getSDKVersion();
其他说明
混淆打包 如果开发者需要使用 proguard 进行混淆打包,请在 proguard 配置文件添加如下代码:
#trustdecision
-keep class com.trustdecision.**{*;}
-keep class cn.tongdun.**{*;}
活体检测功能模块
初始化配置可选参数列表
配置 key | 定义 | 说明 | 示例代码 |
---|---|---|---|
livenessHttpTimeOut | SDK网络超时时间配置(单位:毫秒) | 默认为10 * 1000ms | builder.livenessHttpTimeOut(10000) |
language | 语言类型 | 默认为手机系统语言 Options: en 英语 zh-Hans 简体中文 zh-Hant 繁體中文 es 西班牙语 id 印尼语 ar 阿拉伯语 fil 菲律宾语 ko 韩语 pt 葡萄牙语 ru 俄语 th 泰语 tr 土耳其语 vi 越南语 | builder.language("en") |
playAudio | 是否播报语音 | 默认为 false,不播报语音 | builder.playAudio(true) |
showReadyPage | 启动人脸时,会弹出检测准备页面 | 是否显示准备页面, 默认为 true, 即显示 | builder.showReadyPage(true) |
faceMissingInterval | 没有检测到人脸时的超时时间 | 无人脸超时时间, 单位ms 默认为 1000ms | builder.faceMissingInterval(1000) |
prepareStageTimeout | 准备阶段超时时间 | 准备阶段超时时间, 单位秒 默认为 0S, 即永远不超时 | builder.prepareStageTimeout(0) |
actionStageTimeout | 动作阶段超时时间 | 动作阶段超时时间, 单位秒 默认为 8S | builder.actionStageTimeout(8) |
弹出活体检测
showLiveness方法
通过TDRisk.showLiveness 唤起 活体检测
TDShowLivenessCallback 是活体检测的回调接口,您需要自行实现以下接口:
示例代码
...
public void loginClick() {
TDRisk.showLiveness(new TDRiskLivenessCallback() {
@Override
public void onSuccess(String result) {
Log.d("TD","验证完成: " + result);
}
@Override
public void onError(String errorCode, String errorMsg,String sequenceId) {
Log.d("TD","验证失败!, 错误码:"+ errorCode + ", 错误内容:" + errorMsg + ", seqid" +sequenceId);
}
});
}
Result响应参数
字段 | 类型 | 含义 | 备注 |
---|---|---|---|
code | Integer | API状态码 | 见下方状态码列表 |
message | String | 状态信息提示 | 在 API 异常状态下会输出具体的异常原因 |
sequence_id | String | 响应唯一码 | 用于跟踪每次请求记录的唯一标识 |
image | String | 活体检测人脸图片 | 活体检测过程中抓拍到的最佳人脸图片,base64格式 |
score | Double | 活体检测置信分 | 预留字段,目前仅需要根据code字段结果判断是否通过活体检测(code=200代表真人通过) |
Result示例
{
"code": "200",
"message": "success",
"sequence_id": "1679299854228726325924",
"image": "\/9j\/4AAQSkZJRgABAQAAAQABAAD\/2wBDAAMCA",
"score": 0.98958
}
状态码
代码 | 提示 | 是否计费 |
---|---|---|
200 | success 成功(真人通过) | 是 |
20700 | No face detected 没有检测到人脸 | 否 |
20702 | Person change detected 检测到换人 | 否 |
20703 | Detection timeout 检测超时 | 否 |
20705 | Screen lock or background exit during detection 检测过程中锁屏或退出后台 | 否 |
20710 | No camera permission 没有相机权限 | 否 |
20711 | User actively cancels detection on the preparation page 准备页面用户主动取消检测 | 否 |
20712 | User actively cancels detection on the detection page 检测页面用户主动取消检测 | 否 |
20749 | Inconsistent action, tilt head down 动作不一致做出低头动作 | 否 |
60001 | Network issue, failed to retrieve session 网络问题,无法获取session | 否 |
60002 | Network issue, failed to call anti-hack 网络问题,无法调用anti-hack | 否 |
12202 | Identified as a blink attack 判断为抠眼攻击 | 是 |
12203 | Identified as a mouth movement attack 判断为抠嘴攻击 | 是 |
12204 | Identified as a partial face attack 判断为半张脸攻击 | 是 |
12205 | Identified as a video replay attack 判断为视频回放攻击 | 是 |
12206 | Identified as a black and white image 判断为黑白图片 | 是 |
12207 | Identified as a paper-based attack 判断为纸面攻击 | 是 |
12208 | Identified as a frame (including paper or phone frame) 判断为边框(包括纸面、手机等边框) | 是 |
12209 | Identified as a moire pattern attack 判断为摩尔纹攻击 | 是 |
12210 | Identified as a face superiority attack 判断为脸优攻击 | 是 |
12211 | Identified as a paper-based attack (optical flow) 判断为纸面攻击(光流) | 是 |
12212 | Identified as a mask attack 判断为面具攻击 | 是 |
12213 | Identified as an ID card attack 判断为证卡攻击 | 是 |
12214 | Identified as a 3D mask attack 判断为3D面具攻击 | 是 |
12215 | Identified as a synthetic image attack 判断为合成图像攻击 | 是 |
12216 | Identified as a black-market software attack 判断为黑产软件攻击 | 是 |
12217 | Identified as a T-type mask attack 判断为T型面具攻击 | 是 |
12218 | Identified as a blurry image 判断为模糊图片 | 是 |
12219 | Suspected deepfake image attack 疑似深伪图像攻击 | 是 |
12220 | Suspected high-resolution screen attack 疑似高清屏幕攻击 | 是 |
12222 | Injection attack 注入攻击 | 是 |
12250 | Verification error 其他活体攻击 | 是 |
11350 | Internal error 内部错误 | 否 |