跳到主要内容

🙂 面部主动活体检测

1 IC每次请求🔏 HMAC 签名判定
v1.0 活跃 2026年7月 POST /v3/store/ekyc/face-active-liveness/finalize

欢迎使用面部主动活体检测 API,这是由艾艾普科技有限公司开发的一款人工智能产品。与被动活体检测(仅分析单张图像)不同,主动活体检测会要求用户在摄像头前完成随机挑战动作——眨眼、向左转头、向右转头、微笑——从而证明镜头前确实有一位配合操作的真人。会话在服务器端完成最终判定,API 返回经过加密签名的判定结果,您的后端可以独立验证该签名,因此被篡改的客户端永远无法伪造"通过"的结果。

试用 SDK(实时摄像头)

您可以使用免费开源的 iApp eKYC Web SDK 直接在浏览器中运行完整的挑战动作流程——SDK 会锁定您的面部、发出随机挑战动作、选择最佳自拍帧,并将其提交至 finalize API。更多流程请参阅完整的 SDK 实时演示页面

Loading live demo…

工作原理

整个流程设计为由我们免费开源的 eKYC SDK(Flutter 和网页版)驱动,SDK 在设备端处理摄像头、面部跟踪和挑战动作逻辑:

  1. 面部锁定 — SDK 检测到且仅检测到一张正面人脸,并等待其保持稳定且处于取景框内的合适位置。
  2. 随机挑战动作 — SDK 从眨眼 / 向左转头 / 向右转头 / 微笑中随机抽取 3 个不同的挑战动作,并使用实时面部关键点(face landmarks)在设备端逐一验证(例如,眨眼必须是先闭眼再睁眼的过渡过程,因此闭眼的打印照片无法通过)。
  3. 最佳帧选择 — 在整个会话过程中,SDK 会对每一帧清晰、正面、睁眼的画面进行评分(清晰度 × 面部尺寸),并保留最佳自拍照。
  4. 最终提交(Finalize) — SDK 将最佳自拍照连同带时间戳的挑战日志提交至 POST /v3/store/ekyc/face-active-liveness/finalize
  5. 服务器端复核 — 服务器验证挑战日志(挑战类型须在允许列表内、至少 2 个挑战动作、全部通过、时间戳严格递增、每个挑战的时长合理、会话足够新鲜),并使用我们通过 iBeta Level 1 认证的被动活体检测引擎对自拍照进行独立复核。
  6. 签名判定 — 服务器返回使用 HMAC-SHA256 签名的判定结果。判定结果中嵌入了自拍照的 SHA-256 哈希值,将判定与确切的图像字节绑定。您的后端使用 iApp 签发的共享密钥验证签名,并且只信任经过签名的判定结果——绝不信任客户端自己的声明。

使用 SDK 快速开始

集成主动活体检测最快的方式是使用免费、Apache-2.0 许可的 iApp eKYC SDK — 请参阅 SDK 入门指南

Flutter

# pubspec.yaml
dependencies:
iapp_ekyc_sdk:
git:
url: https://github.com/iapp-technology/iapp-ekyc-sdk.git
path: flutter
import 'package:iapp_ekyc_sdk/iapp_ekyc_sdk.dart';

final client = IappEkycClient(apiKey: 'YOUR_API_KEY');

// 面部主动活体检测,附带服务器签名判定
final liveness = await ActiveLivenessView.start(context, client: client);
if (liveness.verdict.passed) { /* 继续开户流程 */ }

网页版 (JavaScript)

npm install @iapp-technology/ekyc-sdk
import { IappEkyc } from '@iapp-technology/ekyc-sdk';

const ekyc = new IappEkyc({ apiKey: 'YOUR_API_KEY' });

const liveness = await ekyc.startActiveLiveness({
mount: document.getElementById('ekyc-mount'),
});

入门指南

  1. 先决条件

    • 艾艾普科技的 API 密钥
    • eKYC SDK(推荐)或等效的设备端挑战动作实现
    • 自拍照格式:JPEG, JPG, PNG
    • 最大文件大小:10MB
  2. 快速入门

    • 面向 Flutter (Android/iOS) 和网页版的即插即用 SDK 摄像头流程
    • 每次会话均使用随机挑战动作序列
    • 服务器签名判定,实现防篡改集成
    • 由我们通过 iBeta Level 1 认证的被动活体检测引擎提供支持
  3. 主要功能

    • 眨眼、向左转头、向右转头和微笑挑战动作
    • 防作弊:面部丢失、出现多张面部或身份切换时会话将重新开始
    • 最佳帧自拍照选择(按清晰度评分)
    • HMAC-SHA256 签名判定,与自拍照的 SHA-256 哈希绑定
  4. 安全与合规

    • 符合 GDPR 和 PDPA
    • 处理后不保留任何图像数据
    • 签名判定可在您的后端离线验证
如何获取 API 密钥?

请访问 API 密钥管理 页面查看您现有的 API 密钥或申请新密钥。

示例

面部主动活体检测 Finalize 请求:

SDK 会为您自动构建此请求。如果您直接调用 API,请提交最佳自拍帧以及在设备端记录的 JSON 挑战日志:

curl --location 'https://api.iapp.co.th/v3/store/ekyc/face-active-liveness/finalize' \
--header 'apikey: {YOUR API KEY}' \
--form 'file=@"selfie.jpg"' \
--form 'challenges={
"session_id": "b0e7c1a2-4f5d-4e6a-9b8c-7d6e5f4a3b2c",
"sdk": { "name": "iapp-ekyc-sdk-flutter", "version": "0.1.0", "platform": "android" },
"started_at": 1767500000000,
"finished_at": 1767500008000,
"challenges": [
{ "type": "blink", "issued_at": 1767500000123, "completed_at": 1767500001873, "passed": true },
{ "type": "turn_left", "issued_at": 1767500002000, "completed_at": 1767500004100, "passed": true },
{ "type": "smile", "issued_at": 1767500004500, "completed_at": 1767500006900, "passed": true }
]
}'

面部主动活体检测 Finalize 响应:

{
"verdict": {
"passed": true,
"passive_liveness": { "predict": "REAL", "real_score": 0.9999, "threshold": 0.5 },
"challenge_summary": {
"total": 3,
"passed": 3,
"types": ["blink", "turn_left", "smile"],
"duration_ms": 8000,
"valid": true,
"reasons": []
},
"session_id": "b0e7c1a2-4f5d-4e6a-9b8c-7d6e5f4a3b2c",
"selfie_sha256": "ab12cd34ef56ab12cd34ef56ab12cd34ef56ab12cd34ef56ab12cd34ef56ab12",
"timestamp": "2026-07-04T09:00:00.000Z",
"nonce": "9f3a1c7e2b8d4f60"
},
"signature": "hex(HMAC-SHA256(secret, canonicalJSON(verdict)))",
"signature_alg": "HMAC-SHA256",
"process_time": 0.42
}

验证签名 (Node.js):

您的后端必须使用 iApp 签发的共享密钥,对 verdict 的规范化 JSON(所有对象键递归排序、无多余空白字符、UTF-8 编码)重新计算 HMAC,并以恒定时间方式进行比较:

const crypto = require('crypto');
const sortKeysDeep = (v) =>
Array.isArray(v) ? v.map(sortKeysDeep)
: v && typeof v === 'object'
? Object.fromEntries(Object.keys(v).sort().map((k) => [k, sortKeysDeep(v[k])]))
: v;
const canonical = (o) => JSON.stringify(sortKeysDeep(o));
const expected = crypto.createHmac('sha256', SECRET).update(canonical(verdict)).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'));

然后请检查 verdict.passedverdict.timestamp 的新鲜度,以及——如果自拍照是单独传输的——其 SHA-256 是否等于 verdict.selfie_sha256

功能与能力

核心功能

  • 每次会话均使用设备端随机挑战动作序列(眨眼、向左转头、向右转头、微笑)——在设计上即可抵御重放攻击。
  • 使用我们通过 iBeta Level 1 认证的被动活体检测引擎在服务器端复核自拍照。
  • HMAC-SHA256 签名判定,通过 selfie_sha256 将判定与确切的自拍照字节绑定。
  • 严格的挑战日志校验:类型须在允许列表内、至少 2 个挑战动作、时间戳严格递增、单个挑战时长 300 ms–30 s、会话长度 ≤ 120 s、与服务器时间相差不超过 5 分钟。
  • 面向 Flutter (Android/iOS) 和网页版的免费开源客户端 SDK,UI 完全可定制主题,支持英语、泰语和中文。

支持的字段

  • 通过/未通过的活体判定,附带被动活体检测分数和阈值。
  • 每次会话的挑战摘要(类型、数量、时长、校验原因)。
  • 可选返回经验证自拍照的 base64 编码(return_image=true)。
  • 兼容 JPEG、JPG 和 PNG 格式的自拍照。

API 端点

端点方法描述费用
POST /v3/store/ekyc/face-active-liveness/finalizePOST完成主动活体检测会话——校验挑战日志、复核自拍照并返回签名判定1 IC / 请求

API 参考

面部主动活体检测端点

1. Face Active Liveness Finalize

POST /v3/store/ekyc/face-active-liveness/finalize

完成一次主动活体检测会话。校验设备端挑战日志,使用被动活体检测引擎复核最佳自拍帧,并返回 HMAC-SHA256 签名判定。

SDK 是官方推荐的客户端

直接调用此端点需要您自行实现等效的设备端挑战动作(随机选择、实时关键点验证、真实的挂钟时间戳)。eKYC SDK 是官方推荐的客户端,可为您处理上述全部工作。


请求和响应格式

请求头

名称类型描述
apikeyString调用此 API 的 API 密钥

请求体 (multipart/form-data)

名称类型是否必填描述
fileFile会话中的最佳自拍帧(JPEG/PNG,服务器端进行 magic byte 校验,最大 10MB)
challengesString挑战日志的 JSON 字符串——会话 ID、SDK 信息以及每个挑战动作的时间戳(参见上方示例)
return_imageString设置为 "true" 时,将在 selfie 字段中以 base64 形式返回自拍照(默认不返回)

响应中的参数

名称类型描述
verdictDictionary经过签名的活体判定对象
verdict.passedBoolean总体结果——仅当挑战日志有效且自拍照通过被动活体检测时才为 true
verdict.passive_livenessDictionary被动活体复核结果:predict (REAL/SPOOF)、real_scorethreshold
verdict.challenge_summaryDictionary挑战校验结果:totalpassedtypesduration_msvalidreasons
verdict.session_idString从挑战日志回传的会话 UUID
verdict.selfie_sha256String上传自拍照的 SHA-256 哈希值(64 位十六进制字符)——将签名与图像字节绑定
verdict.timestampString判定生成时的服务器时间(ISO 8601)
verdict.nonceString使每个判定唯一的随机数(nonce)
signatureStringverdict 规范化 JSON 计算的十六进制 HMAC-SHA256,密钥为您的共享密钥
signature_algString始终为 HMAC-SHA256
selfieDictionary仅当 return_image=true 时返回:filenamecontent_typesizeimage_base64
process_timeFloat服务器处理时间(秒)

错误代码

代码错误描述
400INVALID_CHALLENGE_LOG / INVALID_IMAGE / MISSING_FIELD挑战日志格式错误、图像无效或缺少必填字段(附带 reasons 数组)
401API 密钥无效缺少或无效的 apikey 请求头(网关)
402积分不足请前往积分页面充值(网关)
413文件过大自拍照超过 10MB 限制
502UPSTREAM_UNAVAILABLE活体检测引擎暂时不可用——请稍后重试
计费说明

返回 "passed": false 的已完成检测仍为 HTTP 200,并计费 1 IC——因为活体检测已实际运行并生成了签名判定。错误响应(400/401/402/413/502)一律不计费。

定价

操作生产路径IC 成本单位本地部署
Face Active Liveness Finalize/v3/store/ekyc/face-active-liveness/finalize1 IC每 1 次请求联系我们