# 视频活体实名核验数字证书服务API

视频实名认证产品:主要用于在H5场景下,通过用户新录制并上传一个视频,进行活体检测的判断,是活体,再对比身份证姓名是否一致,最后比对人脸是否是本人。验证通过后签发具有法律效力的第三方可信数字证书

# 一、请求说明

# 二、请求参数

  • 请求参数以表单形式提交,Content-Type值为: application/x-www-form-urlencoded;charset=utf-8
名称 类型 是否必须 描述
realname String 姓名(身份证);参数支持数据加密,详情参照加解密方法说明
idcard String 身份证号码;参数支持数据加密,详情参照加解密方法说明
livenessRate Double 活体分数阀值,高于阀值才会进行人脸比对
videoData String 视频数据,以base64:开头 (视频base64数据), 以fs: 开头(文件云文件);参数支持数据加密,详情参照加解密方法说明
  • 分数阀值介绍
阀值 拒绝率 误拒率 通过率
0.022403 0.90325733 0.1% 99.9%
0.393241(推荐) 0.96254072 0.5% 99.5%
0.649192 0.97557003 1% 99%
0.933801 0.98990228 2% 98%
0.973637 0.99446254 3% 97%
0.988479 0.99641694 4% 96%
0.994058 0.99739414 5% 95%
  • 关于以上数值的概念介绍:

    • 拒绝率(TRR):如99%,代表100次作弊假体攻击,会有99次被拒绝。
    • 误拒率(FRR):如0.5%,指1000次真人请求,会有5次因为活体分数低于阈值被错误拒绝。
    • 通过率(TAR):如99%,指100次真人请求,会有99次因为活体分数高于阈值而通过。
    • 阈值(Threshold):高于此数值,则可判断为活体。
  • 请求示例:

http或https://api.spiderid.cn/api/router/rest?
<[公共请求参数]>

realname=XXX&idcard=XXX&livenessRate=XXX&videoData=XXX

# 三、响应参数

data 结果信息 类型 描述
incorrect Integer 返回码
message String 描述(100:成功 其他为失败信息)
livingScore Double 活体分数
faceScore Double 人脸比对成功才有,人脸比对分数;faceScore分数在0到1之间,值越大相似度越高,0<faceScore<0.40(系统判断为不同人), 0.40≤faceScore≤0.44(不能确定是否为同一人),0.45≤faceScore(系统判断同一人)
faceAdvise String 人脸比对成功才有,人脸比对建议
pictures List 活体比对成功才有,解析出的图片地址,有效期24小时,过期后下载不了
certificate String 证书

# 四、成功示例

JSON示例

{
   "code": 0,
    "requestId":"dsd24...",
    "message": "success",
    "data": {
        "message": "检测成功",
        "incorrect":100,
        "livingScore":0.9457,
        "faceScore":0.8,
        "faceAdvise":"系统判断为同一人",
        "pictures":[".....",
                    "....."
                   ]
    }
}

# 五、失败示例

JSON示例

{
   "code": 0,
    "requestId":"dsd24...",
    "message": "success",
    "data": {
        "message": "视频活体检测失败",
        "incorrect":124
    }
}

# 六、返回码说明(incorrect)

返回码 描述 是否收费
100 检测成功
110 不支持该视频文件
121 视频未检测到人脸
122 视频检测到多张人脸
123 视频检测人脸质量较差:[光线有问题,人脸模糊等]
124 视频活体检测失败
125 视频活体检测完成,分数过低,未进行人脸比对
126 视频活体检测完成,身份核验失败,身份证姓名不合法
127 视频活体检测完成,身份核验失败,身份证号码和姓名不匹配
128 视频活体检测完成,身份核验失败,身份证号码不存在
129 视频活体检测完成,身份核验成功,人脸比对失败
130 视频活体检测完成,照片质量不合格,未进行人脸比对
131 视频活体检测完成,身份核验成功,库中无照片
132 视频活体检测完成,身份核验成功,特征提取失败
133 视频活体检测完成,身份核验成功,检测到多于一张人脸
134 视频活体检测完成,身份核验成功,图片不合法

# SDK 请求示例

    public static void main(String[] args) {
        //提供的url
        String url = "http://api.spiderid.cn/api/router/rest";
        //您的appKey
        String appkey = "XXX";
        //您的appSecret
        String secretKey = "XXX";

        try {

            //1.默认客户端
            ApiClient apiClient = new DefaultApiClient(url, appkey, secretKey);

            //2.调用出错自动重试客户端
            //AutoRetryApiClient apiClient = new AutoRetryApiClient(url, appkey, secretKey);

            VideoLivenessAuthRequest req = new VideoLivenessAuthRequest();
            req.setRealname("XXX");
            req.setIdcard("XXX");
            req.setLivenessRate(0.393241);

//            //1.以base64:开头,图片转换成base64位字符串
//            String video = Base64.encodeBase64String(FileUtils.readFileToByteArray(new ClassPathResource("/data/qq.mp4").getFile()));
//            req.setVideoDataBase64(video);

            //2.fs:开头,需要调用我们提供的上传接口,获取bucket,和objectKey,格式为:fs:+bucket:+objectKey
            String bucket = "XXX";
            String objectKey = "XXX";
            String videoData = bucket + ":" + objectKey;

            req.setVideoDataFs(videoData);

            // 配置此参数时,会对请求参数中的realname、realname、videoData属性做加密
//            req.setEncMethod(EncryptMethod.SM4);
            // 当设置encMethod后,fs上传文件也需要加密
//            byte[] encPassword = SecretGenerateUtils.getSecretKey(appkey, secretKey);
//            String fsKey = uploadFile(apiClient, "liveness_video", "/data/qq.mp4", encPassword);
//            req.setVideoDataFs(fsKey);
            
            VideoLivenessAuthResponse rsp = apiClient.execute(req);
            //后续业务处理
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 上传文件
     *
     * @param apiClient   客户端
     * @param bizType     文件上传业务类型
     * @param path        需要上传的文件路径
     * @param encPassword 文件加密密码,不为null对文件进行加密
     * @return bucket:objectKey
     */
    private static String uploadFile(ApiClient apiClient, String bizType, String path, byte[] encPassword) throws ApiException, IOException {

        FsUploadPolicyRequest fsUploadPolicyRequest = new FsUploadPolicyRequest();
        fsUploadPolicyRequest.setBizType(bizType);
        //获取文件上传权限
        FsUploadPolicyResponse fsResponse = apiClient.execute(fsUploadPolicyRequest);
        //获取权限识别
        if (null == fsResponse.getData()) {
            throw new ApiException();
        }
        //上传文件示例
        Map<String, String> params = new HashMap<String, String>(5);
        params.put("token", fsResponse.getData().getToken());
        if (fsResponse.getData().getObjectKey().endsWith("/")) {
            params.put("key", fsResponse.getData().getObjectKey() + "${filename}");
        } else {
            params.put("key", fsResponse.getData().getObjectKey());
        }
        //需要上传的文件
        Map<String, FileItem> fileParams = new HashMap<String, FileItem>(5);

        File file = new File(path);
        // encPassword不为空对上传的文件进行加密
        if (encPassword != null) {
            byte[] bytes = FileUtils.readFileToByteArray(file);
            byte[] encryptContent = Sm4Utils.encrypt(bytes, encPassword);
            String fileName = file.getName();
            FileItem fileItem = new FileItem(fileName, encryptContent, FileContentTypeUtils.mimeTypeByFilename(fileName));
            fileParams.put("file", fileItem);
        } else {
            fileParams.put("file", new FileItem(file));
        }

        //上传
        String uploadUrl = fsResponse.getData().getUploadUrl();
        String json = WebUtils.doPost(uploadUrl, params, fileParams, 30000, 30000);
        JSONObject jsonObject = JSON.parseObject(json);

        return jsonObject.getString("bucket") + ":" + jsonObject.getString("objectKey");
    }

最后更新于: 1/12/2024, 5:28:52 PM