@ capgo/ 电容- app- test
向您的后端证明请求来自您在真实设备上的真应用程序: iOS上的 App Attest 和Android上的 Google Play Guide, 一个API 后面. Block bots,被修改的应用程序和API滥用.
🤖 建筑与AI编码代理? 安装 Capgo 技能 所以克劳德代码,代码,光标,副驾驶,或双子座CLI知道如何安装和使用
@capgo/capacitor-app-attest在您的电容应用程序中:npx skills add Cap-go/capgo-skills。然后问你的经纪人: 添加@capgo/capor-app-atest 到我的Capacitor应用软件上,并把它接上 代理设置指南 • 妇女 主机磁共振
主要特点
- 证明数字 :
createAttestation()创建注册符,以响应您后端发布的质疑. - 要求的断言数字 :
createAssertion()签名请求的有效载荷,使服务器能够验证每个呼叫. - 密钥处理数字 :
prepare()在 iOS 上创建 App Attest 密钥,并在 Android 上准备 Play Guide 令牌提供者.storeKeyId(), (中文(简体) ),getStoredKeyId()财务报告和审定财务报表clearStoredKeyId()管理密钥ID,它持续在iOS上,并持续到Android上的进程. - 能力数字 :
isSupported()财务报告和审定财务报表getCapabilities()报告当前设备提供的内容. - 额外欺诈信号数字 :
getDeviceCheckToken()iOS 设备检查和getWidevineFingerprint()安卓号. - 平台: iOS和Android. 互联网档案馆的存檔,存档日期2013-12-21. iOS使用App Attest和December Check,Android使用Play完整性标准API. 证明电话在网络上.
跨平台设备 Capacitor 验证 :
- iOS: App Attest (英语:
DeviceCheck)和可选设备检查符 - Android: Google 播放完整性标准 API 证书
- 可选的Android欺诈信号: Widevine DRM指纹
为什么这个插件
此插件为您提供了两个平台的 JavaScript API, 而只使用本地验证系统 :
- iOS使用"苹果App Attest"(苹果App Attest).
- Android使用Google Play完整性标准API.
- 可选的Android Widevine支持为需要DRM支持的欺诈信号的应用程序单独曝光.
- 没有自定义密码, 没有随机的app- side 安全方案 .
- 联合来文方法相同,两个平台输出形状相同(
platform, (中文(简体) ),format, (中文(简体) ),token, (中文(简体) ),keyId) (中文(简体) ).
用于硬化登录,账户恢复,支付,促销滥用检查等高风险端点.
安保模式
验证只在您的后端验证时才会增加值 .
- 永远不要仅仅相信客户端的成功.
- 总是验证 App Attest / 播放完整性有效载荷服务器侧.
- 拒绝失败签名、非ce、app身份或环境检查的标志/证书.
- 将 Widevine 值视为敏感的标识符 。 仅用于欺诈/安全,在隐私政策中披露用途,不与广告标识相通.
- iOS不会暴露出稳定的设备指纹. 使用 App Attest 和设备检查 .
统一 API 设计
建议的API:
prepare()createAttestation()createAssertion()
可选的欺诈标志方法:
getCapabilities()getWidevineFingerprint()(仅Android,可选)getDeviceCheckToken()(仅iOS)
相容性的后遗症别名仍然可用 :
generateKey()=>prepare()attestKey()=>createAttestation()generateAssertion()=>createAssertion()
在iOS和Android上,结果包括:
platform数字 :ios或者说androidformat数字 :apple-app-attest或者说google-play-integrity-standardtoken: 用于后端校验的正则字段
文档
这里有最完整的医生: https://capgo.app/docs/plugins/app-atests/ 互联网档案馆的存檔,存档日期2014-12-21
兼容性
| 插件版本 | 电容兼容性 | 维护 |
|---|---|---|
| v八.。 。 。 . | v八.。 。 。 . | ✅ |
| v.。 。 。 . | v.。 。 。 . | 应要求 |
| v6 (英语).。 。 。 . | v6 (英语).。 。 。 . | ❌ |
| 页:1.。 。 。 . | 页:1.。 。 。 . | ❌ |
说明: 此插件的主要版本沿用了Capacitor的主要版本. 使用匹配您的 Capacitor 安装的版本( 例如, Capacitor 8 的插件 v8) .
安装( 电源 8)
您可以使用我们的 AI 辅助设置安装插件 。 使用以下命令将 Capgo 技能添加到您的 AI 工具 :
npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins
然后使用下列提示:
Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-app-attest` plugin in my project.
如果您更喜欢手动设置,请通过运行以下命令来安装插件,并遵循下面的平台特定指令:
npm install @capgo/capacitor-app-attest
npx cap sync
平台设置
iOS系统
- 在 Xcode 中打开您的应用目标 .
- 启用
App Attest能力(低于Signing & Capabilities) (中文(简体) ). - 在物理设备上运行( App Attest 并非在所有模拟语境中都可以使用) .
机器人
- 启用 播放完整性 API 在你的谷歌云项目.
- 在 Play Console 为您的应用程序配置完整性访问 .
- 设定
cloudProjectNumber在控制配置中:
// capacitor.config.ts
plugins: {
AppAttest: {
cloudProjectNumber: '123456789012'
}
}
也可以通过 cloudProjectNumber 直接在方法选项中.
此插件使用 标准完整性 API 流经Android(prepareIntegrityToken + 键 request) (中文(简体) ).
关于Android, prepare() 准备本地标准完整性提供者并返回一个手柄(keyId),用于随后的通话.
威德文指纹是可选的. 它不需要额外的Android权限或额外的设置,也不被使用 prepare(), (中文(简体) ), createAttestation(),或 createAssertion()。只有电话 getWidevineFingerprint() 如果你的应用程序需要这个信号.
使用量
import { AppAttest } from '@capgo/capacitor-app-attest';
const support = await AppAttest.isSupported();
if (!support.isSupported) {
return;
}
const prepared = await AppAttest.prepare();
const keyId = prepared.keyId;
const registration = await AppAttest.createAttestation({
keyId,
challenge: 'server-registration-challenge',
});
const assertion = await AppAttest.createAssertion({
keyId,
payload: 'request-payload-or-nonce-from-backend',
});
// registration.token and assertion.token are verified server-side.
console.log(registration, assertion);
const capabilities = await AppAttest.getCapabilities();
if (capabilities.platform === 'android' && capabilities.widevine.supported) {
const widevine = await AppAttest.getWidevineFingerprint();
await api.storeWidevineFingerprint(widevine.widevineIdSha256);
}
if (capabilities.platform === 'ios' && capabilities.deviceCheck.supported) {
const deviceCheck = await AppAttest.getDeviceCheckToken();
await api.verifyDeviceCheckToken(deviceCheck.token);
}
后端处理
您的后端必须分支到 platform编号 :format 并运行该平台的本地验证流程.
iOS 后端( Apple Apple Attest) (英语)
登记createAttestation:
- 在您的后端产生一次性随机挑战 .
- 把挑战送到应用程序上.
- App电话
prepare()曾经,那么createAttestation({ keyId, challenge })。 。 。 . - 后端用 App Attest 规则验证证明:
- 证书链有效并被锁定到 App Attest.
- App 身份符合您的捆绑/团队 .
clientDataHash对应于SHA256(challenge)。 。 。 .
- 存储此设备/ 用户的关键材料状态( E)
keyId公用钥匙 校对者提供的反元数据.
请求保护createAssertion:
- 后端构建每请求一次性有效载荷/非有效载荷(或Cononical request hash introduction).
- App电话
createAssertion({ keyId, payload })。 。 。 . - 后端使用存储的iOS App Attest 密钥上下文验证断言签名.
- 强制重放保护(单用非ce + 过期 + 从核查器输出出单音节计数).
设备检查( E)getDeviceCheckToken:
- App电话
getDeviceCheckToken()。 。 。 . - 后端向Apple的"设备检查"服务器API发送了该令牌.
- 后端维护了苹果的"设备检查服务"中该设备的两个欺诈/风险比特.
Android 后端( Play 完整性标准 API)
登记createAttestation:
- 在您的后端产生一次性随机挑战 .
- App电话
createAttestation({ keyId, challenge })。 。 。 . - 后端用 Google Play Guide 服务器 API 解码返回的 Play Guide 令牌(
decodeIntegrityToken) (中文(简体) ). - 至少验证 :
requestDetails.requestHash等于base64url(SHA256(challenge))。 。 。 .appIntegrity.packageName符合您的应用标识 .appIntegrity.certificateSha256Digest包含您的发行签名证书摘要.appIntegrity.appRecognitionVerdict符合您的政策( 通常为PLAY_RECOGNIZED) (中文(简体) ).deviceIntegrity.deviceRecognitionVerdict符合您的政策(例如:MEETS_DEVICE_INTEGRITY) (中文(简体) ).
- 长期证明决定/状态与用户/设备会话挂钩.
请求保护createAssertion:
- 后端发布一次性请求有效载荷/空取.
- App电话
createAssertion({ keyId, payload })。 。 。 . - 后端解码符和检查
requestHash === base64url(SHA256(payload))。 。 。 . - 拒绝重复使用/过期的有效载荷,并强制执行你的廉正判决政策.
宽宽( W)getWidevineFingerprint:
- 只有在您的欺诈政策需要基于 DRM 的标识符信号时才会打电话 .
- 存储
widevineIdSha256默认. - 请求
widevineIdBase64仅使用includeRawId: true当您明确需要原始标识符时. - 不使用Widevine值进行广告,归属,或交叉应用跟踪.
工作流程计划
统一跨平台流量
flowchart TD
A[Backend creates one-time challenge/payload] --> B[App calls AppAttest plugin]
B --> C{platform}
C -->|iOS| D[Apple App Attest]
C -->|Android| E[Play Integrity Standard]
D --> F[token + format + platform + keyId]
E --> F
F --> G[App sends token + context to backend]
G --> H{backend verification by format}
H -->|apple-app-attest| I[App Attest verification]
H -->|google-play-integrity-standard| J[Play Integrity decode + policy checks]
I --> K[allow or deny]
J --> K
iOS工作流程计划(登记+断言)
sequenceDiagram
participant App as Mobile App (iOS)
participant Plugin as @capgo/capacitor-app-attest
participant Apple as Apple App Attest
participant BE as Backend
BE->>App: registrationChallenge
App->>Plugin: prepare()
Plugin->>Apple: generateKey()
Apple-->>Plugin: keyId
Plugin-->>App: keyId
App->>Plugin: createAttestation(keyId, challenge)
Plugin->>Apple: attestKey(keyId, SHA256(challenge))
Apple-->>Plugin: attestationObject
Plugin-->>App: token + platform + format + keyId + challenge
App->>BE: token + keyId + challenge
BE->>BE: verify cert chain + app identity + clientDataHash
BE-->>App: registration accepted/rejected
BE->>App: requestPayload/nonce
App->>Plugin: createAssertion(keyId, payload)
Plugin->>Apple: generateAssertion(keyId, SHA256(payload))
Apple-->>Plugin: assertion
Plugin-->>App: token + platform + format + keyId + payload
App->>BE: token + keyId + payload
BE->>BE: verify signature + counter + replay policy
BE-->>App: request allowed/denied
Android工作流程计划(登记+断言)
sequenceDiagram
participant App as Mobile App (Android)
participant Plugin as @capgo/capacitor-app-attest
participant PlaySDK as Play Integrity SDK
participant BE as Backend
participant Google as Google decodeIntegrityToken API
Note over App,BE: One-time provider preparation
App->>Plugin: prepare({ cloudProjectNumber })
Plugin->>PlaySDK: prepareIntegrityToken(...)
PlaySDK-->>Plugin: tokenProvider handle (keyId)
Plugin-->>App: keyId
BE->>App: registrationChallenge
App->>Plugin: createAttestation(keyId, challenge)
Plugin->>PlaySDK: request(requestHash=base64url(SHA256(challenge)))
PlaySDK-->>Plugin: integrityToken
Plugin-->>App: token + platform + format + keyId + challenge
App->>BE: token + keyId + challenge
BE->>Google: decodeIntegrityToken(token)
Google-->>BE: decoded integrity payload
BE->>BE: verify requestHash + packageName + cert digest + verdict policy
BE-->>App: registration accepted/rejected
BE->>App: requestPayload/nonce
App->>Plugin: createAssertion(keyId, payload)
Plugin->>PlaySDK: request(requestHash=base64url(SHA256(payload)))
PlaySDK-->>Plugin: integrityToken
Plugin-->>App: token + platform + format + keyId + payload
App->>BE: token + keyId + payload
BE->>Google: decodeIntegrityToken(token)
Google-->>BE: decoded integrity payload
BE->>BE: verify requestHash + replay/ttl + verdict policy
BE-->>App: request allowed/denied
建议的后端有效载荷合同
从应用程序到后端的注册有效载荷:
{
"platform": "ios | android",
"format": "apple-app-attest | google-play-integrity-standard",
"keyId": "string",
"challenge": "string",
"token": "string"
}
从应用到后端的搜索有效载荷 :
{
"platform": "ios | android",
"format": "apple-app-attest | google-play-integrity-standard",
"keyId": "string",
"payload": "string",
"token": "string"
}
重要的后端笔记
- 验证挑战/负载必须生成服务器侧.
- 将每个挑战/负载作为短TTL的单用处理.
- 按环境(dev/staging/prod)保留包 id 和 cert 文摘的许可列表.
- 逻辑校验失败, 带有理性代码; 绝不沉默地接受失败 .
- 不要使用此插件来替代认证/会话控件, 请使用它作为额外的信任信号 .
API 密码
isSupported()getCapabilities()prepare(...)createAttestation(...)createAssertion(...)getWidevineFingerprint(...)getDeviceCheckToken()storeKeyId(...)getStoredKeyId()clearStoredKeyId()generateKey(...)attestKey(...)generateAssertion(...)- 接口
- 类型异名
Capacitor 的统一跨平台验证插件.
建议的方法:
prepare()createAttestation()createAssertion()
相容性的后遗症别名仍然可用 :
generateKey()attestKey()generateAssertion()
已支持 ()
isSupported() => Promise<IsSupportedResult>
检查此设备是否有本地证明 .
回返情况: Promise<IsSupportedResult>
获取能力( )
getCapabilities() => Promise<AppAttestCapabilities>
返回现有平台提供的证明和可选的欺诈标志能力.
Widevine是Android独占和可选的. 不需要使用 Widevine 方法的应用程序 广文特有设置.
回返情况: Promise<AppAttestCapabilities>
准备(...)
prepare(options?: PrepareOptions | undefined) => Promise<PrepareResult>
准备验证状态,并返回用于以后调用的键柄.
iOS:生成真正的 App Attest 密钥标识符. Android:准备一个Play完整性标准令牌提供者手柄.
| 参数 | 类型 |
|---|---|
options | PrepareOptions |
回返情况: Promise<PrepareResult>
创建 Atterstation (...)
createAttestation(options: CreateAttestationOptions) => Promise<CreateAttestationResult>
创建绑定在后端所发挑战的注册验证符 .
iOS: 返回 App Attest attestationObject。 。 。 .
Android: 返回 Play 完整性标准令牌.
| 参数 | 类型 |
|---|---|
options | CreateAttestationOptions |
回返情况: Promise<CreateAttestationResult>
创建 Assertion (...)
createAssertion(options: CreateAssertionOptions) => Promise<CreateAssertionResult>
创建与请求的有效载荷相绑定的请求断言符号.
iOS:返回 App Attest 断言. Android: 返回 Play 完整性标准令牌.
| 参数 | 类型 |
|---|---|
options | CreateAssertionOptions |
回返情况: Promise<CreateAssertionResult>
获取Widevine Fingerprint (...)
getWidevineFingerprint(options?: WidevineFingerprintOptions | undefined) => Promise<WidevineFingerprintResult>
返回可选的Android Widevine衍生指纹.
这种方法只使用Android,不属于正常的证明流. 只有当 您的应用程序需要一个基于 DRM 的欺诈信号, 您的隐私政策覆盖了该使用 .
默认 fingerprint 是SHA -256 在威德文设备上 独一无二的ID和盐.
若为 hashSalt 未提供,Android使用应用程序包名作为盐.
原始的 Widevine ID 敏感,只有在 includeRawId 这是真的.
| 参数 | 类型 |
|---|---|
options | WidevineFingerprintOptions |
回返情况: Promise<WidevineFingerprintResult>
获取Device检查托肯 ()
getDeviceCheckToken() => Promise<DeviceCheckTokenResult>
为服务器侧欺诈状态检查创建 iOS 设备检查符 .
回返情况: Promise<DeviceCheckTokenResult>
存储KeyId(...)
storeKeyId(options: StoreKeyIdOptions) => Promise<OperationResult>
存储/准备用于再利用的关键标识符.
iOS:在UserDefaults中坚持. Android:为内存中的此密钥 ID( 进程寿命) 准备本地 Play Guide 提供者 .
| 参数 | 类型 |
|---|---|
options | StoreKeyIdOptions |
回返情况: Promise<OperationResult>
获取StoredKeyId ()
getStoredKeyId() => Promise<GetStoredKeyIdResult>
返回当前存储/准备的密钥标识符 .
Android 值只在过程存在时可用.
回返情况: Promise<GetStoredKeyIdResult>
清除 StoredKeyId ()
clearStoredKeyId() => Promise<OperationResult>
清除存储/准备的关键标识符.
回返情况: Promise<OperationResult>
生成Key(...)
generateKey(options?: PrepareOptions | undefined) => Promise<GenerateKeyResult>
遗留别名 prepare()。 。 。 .
| 参数 | 类型 |
|---|---|
options | PrepareOptions |
回返情况: Promise<PrepareResult>
验证关键(...)
attestKey(options: AttestKeyOptions) => Promise<AttestKeyResult>
遗留别名 createAttestation()。 。 。 .
| 参数 | 类型 |
|---|---|
options | CreateAttestationOptions |
回返情况: Promise<AttestKeyResult>
生成 Assertion (...)
generateAssertion(options: GenerateAssertionOptions) => Promise<GenerateAssertionResult>
遗留别名 createAssertion()。 。 。 .
| 参数 | 类型 |
|---|---|
options | CreateAssertionOptions |
回返情况: Promise<GenerateAssertionResult>
接口
支持的结果
| Prop | 类型 |
|---|---|
isSupported | boolean |
platform | AttestationPlatform |
format | AttestationFormat |
AppAppest 能力
| Prop | 类型 | 说明 |
|---|---|---|
platform | AttestationPlatform | 平台目前正在执行插件 . |
appAttest | SupportStatus | App App Attest 支持 (英语). |
playIntegrity | SupportStatus | Android Play 诚信支持. |
deviceCheck | SupportStatus | iOS 设备检查支持 . |
widevine | WidevineCapabilities | 可选的Android Widevine DRM支持. |
支助现状
| Prop | 类型 | 说明 |
|---|---|---|
supported | boolean | 在当前设备上是否具备此能力 . |
宽宽能力
| Prop | 类型 | 说明 |
|---|---|---|
supported | boolean | Widevine DRM方案是否由设备支持. |
fingerprintAvailable | boolean | 能否尝试使用 Widevine 指纹 。 呼叫时确认实际进入 getWidevineFingerprint()。 。 。 . |
securityLevelScanSupported | boolean | Widevine 安全级别属性是否可以读取 . |
准备结果
| Prop | 类型 |
|---|---|
keyId | string |
platform | AttestationPlatform |
format | AttestationFormat |
准备选项
| Prop | 类型 | 说明 |
|---|---|---|
cloudProjectNumber | string | 仅限Android. Google Cloud project number for Play Guide. Google Cloud project 互联网档案馆的存檔,存档日期2013-12-22., p. 可通过 Capacitor 配置在全球设置 plugins.AppAttest.cloudProjectNumber。 。 。 . |
创建 Attestation 结果
| Prop | 类型 | 说明 |
|---|---|---|
token | string | 统一证明符号值 。 iOS: Base64 App Attest验证. Android:玩"诚信"代币. |
keyId | string | |
challenge | string | |
platform | AttestationPlatform | |
format | AttestationFormat |
创建 Attestation 选项
| Prop | 类型 |
|---|---|
keyId | string |
challenge | string |
cloudProjectNumber | string |
创建自动响应
| Prop | 类型 | 说明 |
|---|---|---|
token | string | 统一断言符号值. iOS: Base64 App Attest断言. Android:玩"诚信"代币. |
keyId | string | |
payload | string | |
platform | AttestationPlatform | |
format | AttestationFormat |
创建代理选项
| Prop | 类型 |
|---|---|
keyId | string |
payload | string |
cloudProjectNumber | string |
宽宽指纹
| Prop | 类型 | 说明 |
|---|---|---|
platform | 'android' | 永远 android。 。 。 . |
source | 'widevine' | 永远 widevine。 。 。 . |
fingerprint | string | 将SHA-256指纹与用户记录并存. |
widevineIdSha256 | string | Widevine设备独有的ID的无盐SHA-256散列. |
widevineIdBase64 | string | Raw Widevine设备独有的ID被编码为base64. 只在 includeRawId 这是真的. |
securityLevel | string | 可用时宽度安全级别, 例如 L1 或者说 L3。 。 。 . |
vendor | string | 可用的DRM供应商 . |
version | string | DRM 插件版本可用时 . |
description | string | 可用时 DRM 插件描述 . |
宽宽字体打印选项
| Prop | 类型 | 说明 |
|---|---|---|
includeRawId | boolean | 返回原始的Widevine设备独有的ID作为基座64. 默认为 false。 。 。 . |
hashSalt | string | 用来制取的可选盐 fingerprint. Android 省略时使用应用程序包名. |
设备检查托肯结果
| Prop | 类型 | 说明 |
|---|---|---|
token | string | iOS 设备检查令牌被编码为 Base64. |
行动结果
| Prop | 类型 |
|---|---|
success | boolean |
存储 KeyId 选项
| Prop | 类型 |
|---|---|
keyId | string |
cloudProjectNumber | string |
获取 StoredKeyId 结果
| Prop | 类型 |
|---|---|
keyId | string | null |
hasStoredKey | boolean |
测试关键结果
| Prop | 类型 | 说明 |
|---|---|---|
attestation | string | 遗产场等于 token。 。 。 . |
生成自动响应
| Prop | 类型 | 说明 |
|---|---|---|
assertion | string | 遗产场等于 token。 。 。 . |
类型异名
证明 平台
'ios' | 'android' | 'web'
证明格式
'apple-app-attest' | 'google-play-integrity-standard' | 'web-fallback'
生成关键选项
生成关键结果
测试关键选项
生成辅助选项
贷项
iOS App Attest 流量来自原始插件 ludufre/capacitor-app-attest。 。 。 .
此插件中的Android支持由Google Play Guide执行,以提供等效的证明覆盖.