先看结论与判断条件

  • 每项能力声明必须绑定明确的 APK、AAB、IPA 或 SO 摘要;演示包、旧版本与通用报告不能代替采购候选。
  • 保护范围要说明处理对象、未处理对象、运行时暴露、服务端边界和失败条件,不能只列功能名称。
  • 兼容性证据要给出真实设备、系统、ABI、场景、结果与失败记录,单个截图和总体通过率都不足以复核。
  • 供应链证明应把产物 subject 摘要、构建者、构建类型、参数与材料绑定,并验证声明类型和签发者身份。
  • Android 与 Apple 的签名链必须分别验收;签名有效证明身份和完整性,不自动证明业务安全或加固强度。
  • 采购问卷应把缺失、过期、错配和不可复核证据直接标为阻塞,而不是用供应商排名或营销承诺补齐。

把能力询问改写成证据问题

采购常见问法是是否支持代码混淆、防篡改、VMP、反调试或全机型兼容,供应商很容易回答支持,却没有说明支持对象、配置、版本、边界和验证方法。可核验证据问卷要把每个名词改写成一条可失败的陈述,并要求对应候选、证据类型、复核步骤与限制。

例如不要问是否兼容 Android,而要问:哪一个候选摘要在什么型号、系统、ABI、业务场景和加固配置下完成了什么测试,失败用例如何记录,未覆盖哪些组合。不要问防逆向强不强,而要问保护了哪些代码、运行时何处仍可能出现明文、测试者使用什么授权方法、结果能证明什么与不能证明什么。

问卷本身不是评分游戏。没有事实依据时,不应根据回答篇幅、术语数量或承诺强度给供应商排位。评审只判断证据是否存在、是否绑定当前候选、是否在有效期内、是否可由买方复核以及结论是否越过证据边界。

宣传问题与证据问题的转换
宣传问法证据问法必须绑定拒绝条件
是否防逆向哪些对象经过何种验证候选与保护范围只给功能列表
是否全兼容哪些矩阵和路径通过设备、系统、ABI 与场景只给总体口号
是否安全针对哪类威胁与边界威胁模型和失败条件没有边界
是否不影响性能同条件基线如何比较原始样本与方法只给单个数字
是否可信构建provenance 指向哪个产物subject 摘要和签发者摘要错配
是否签名完整交付后由谁签名验证平台签名身份混用平台规则

第一组问题锁定交付候选身份

要求供应商列出输入与输出产物的文件名、SHA-256、大小、平台、版本、架构、处理时间和配置标识。APK 与 AAB 还要记录 applicationId、versionCode、签名证书身份;IPA 记录 bundle identifier、版本和 Apple 签名链相关身份;独立 SO 则记录 ABI、SONAME 和 build ID。

输入输出摘要建立了加固转换关系。若供应商展示的报告只写某版本应用,却没有文件摘要,买方无法确认报告属于当前采购候选。相同版本号也可能因重新构建、依赖变化、渠道资源或加固参数不同而产生新字节,旧报告不得自动继承。

还要问交付物由谁保存、如何传输、保留多久、如何删除,以及日志和符号是否包含客户代码或敏感数据。供应商可以用脱敏与受控访问保护材料,但不能因保密而省略证据身份。买方至少要拿到可验证摘要、回执索引和在争议时调阅完整证据的责任人。

候选身份的最低交付字段
对象身份字段验证动作不能证明
APK摘要、包名、版本、证书解析并验签业务安全
AAB摘要、模块、版本、签名者核对 bundle 身份最终每台设备 APK
IPA摘要、bundle id、证书链平台签名检查运行路径正确
SO摘要、ABI、SONAME、build IDELF 身份检查动态装载成功
报告摘要、生成时间、工具版本与候选索引对应报告内容真实
配置配置摘要和审批绑定输入输出保护效果已验证

第二组问题要求公开保护边界

OWASP MASVS-RESILIENCE 将抗篡改与抗逆向放在移动端韧性控制中,但控制目录不证明某个候选达到任何强度。供应商应说明处理哪些 DEX 类、Native 函数、资源、配置和完整性检查点,哪些内容因反射、框架、动态加载、性能或合规要求被排除。

问清攻击面和信任边界:客户端代码在合法设备运行时何处必须解密或执行,密钥是否由服务端授权,离线场景如何限制,篡改发现后采取什么业务动作。加固属于纵深防御,不能替代服务端权限、风控、发布签名和漏洞修复。把所有风险都归给客户端保护会制造错误采购预期。

每项保护还要给出失败条件和可观测性。完整性检查可能因环境、分发重签或系统差异触发;虚拟化范围可能受性能与兼容边界限制;反调试可能影响合法诊断。供应商应列出支持、限制、例外和回滚方式,而不是承诺无法绕过或绝对安全。

保护边界问卷字段
字段采购问题合格回答风险回答
保护对象哪些类、函数或资源处理范围可枚举并绑定配置全部保护
排除对象为什么未处理原因与影响明确没有例外
运行时边界何时出现可执行明文场景与限制明确永不暴露
服务端职责哪些授权不在客户端接口和失败语义明确客户端独立解决
失败动作检测后如何处理可测试且可回滚自动绝对阻断
诊断影响崩溃和符号如何还原有受控映射链不需要调试

第三组问题审查兼容与性能证据

兼容报告必须给出设备型号、系统版本、ABI、芯片、安装来源、应用场景、前置状态、操作步骤和实际结果。测试入口至少覆盖冷启动、登录或授权、核心路径、Native 调用、前后台、多进程、异常和升级。只给设备数量或通过率,买方无法判断关键用户路径是否真正执行。

性能证据要同时提供基线候选和加固候选,保持设备、数据、步骤、冷暖状态、采样工具与统计口径一致。启动、内存、包体、CPU 和耗电是不同指标,不能用一个平均数字代表全部影响。供应商需要交付原始样本摘要、汇总方法、异常样本处理和置信边界。

失败记录比全绿截图更有价值。问卷应要求列出失败设备、失败步骤、错误类型、复现率、根因状态、临时规避和未解决限制。若供应商声称没有失败,应提供测试总集与原始回执,使买方能验证分母和排除规则,而不是把未执行用例当作通过。

兼容与性能证据的合格形态
证据必须包含可复核方式常见缺陷
设备矩阵型号、OS、ABI 和实际结果按用例抽查只列设备名
场景回执步骤、断言和时间重放关键路径只看启动
崩溃材料日志、tombstone 和候选身份匹配符号与摘要缺少同构建材料
性能基线同条件双候选核对原始样本比较条件变化
失败台账未解决项和边界复现与责任人只给全绿汇总
有效期平台与工具版本到期重新验证永久有效

第四组问题追问测试方法与复核责任

每项结论都应回答谁测试、何时测试、使用什么工具版本、输入是什么、通过条件是什么、失败时保存什么以及谁批准。自动化 exit code、编译通过或静态扫描不能替代设备端业务验收。买方应能抽取关键用例,在自己的候选和设备上重复执行。

测试方法要区分静态证据、动态证据和人工判断。静态证据可以确认结构、签名、符号与配置;动态证据确认装载、路径和设备行为;人工判断解释保护范围和商业限制。三者混在一段文字里,容易把配置存在误写成运行通过。

复核责任必须落到角色,而不是写双方确认。供应商负责生成和解释加固回执,买方负责提供真实业务路径与接受标准,独立测试人员负责复现指定证据,发布负责人根据缺口作决定。证据过期、候选变化或平台升级时,由谁触发重验也要写入合同附件。

第五组问题核对构建证明与声明主体

SLSA Provenance v1.1 要求构建证明把产物 subject、构建者、构建类型、外部参数和依赖材料组织起来。采购方先检查 subject digest 是否等于交付候选;摘要不一致时,这份 provenance 属于另一个产物,后续构建信息不能用于当前验收。

in-toto Attestation Statement v1 用 subject、predicateType 和 predicate 表达有类型的声明。格式正确只说明可按预定结构读取,不保证内容真实。还要验证签发主体、签名、证书或密钥信任范围、撤销状态、签发时间以及 predicate 类型是否在采购策略中允许。

无法提供完整构建证明时,供应商可以提交较低等级的来源和处理回执,但必须诚实标注证据类型。接收记录只能证明某人收到某摘要,处理日志只能证明某工具声称执行某步骤,都不能冒充可复现构建。买方可按风险决定阻塞、限制范围或要求补证。

供应链证明的分层验收
层级检查项失败含义采购动作
Subject摘要匹配交付物报告指向其他候选直接阻塞
Predicate type声明类型受支持语义未知或错用阻塞或人工复核
Signer签发者在信任范围声明可被任意伪造直接阻塞
Builder构建者和环境可识别构建来源不清要求补证
Materials输入和依赖可追溯供应链存在断点限制接入
Validity时间、撤销和策略有效证据过期重新签发或重验

Android 与 Apple 签名证据要分别检查

AOSP app signing 说明 Android 使用应用签名建立更新身份,不同 APK 签名方案覆盖不同文件区域和平台版本。问卷要说明输入由谁签名、加固处理是否保留或移除签名、输出由谁签名、使用哪些方案验证,以及应用商店或企业分发如何完成最终签名。

Apple app code signing process 说明 Apple 平台通过代码签名、证书与运行验证建立 App 身份。iOS 交付需要单独说明证书、provisioning、entitlements、bundle 身份和重签责任。不能拿 Android 的 v2、v3 等术语解释 IPA,也不能把 Apple 验签截图当成 Android 更新身份回执。

两种平台上,签名有效都不等于代码没有漏洞、保护强度足够或业务逻辑安全。签名证据回答是谁为哪些字节背书以及内容是否在覆盖范围内变化;保护证据回答处理与验证;兼容证据回答运行路径。问卷必须保留这三类结论的独立性。

平台签名问卷的分离字段
平台身份对象主要问题禁止混淆
Android APK证书与签名方案输入输出由谁签名不套用 Apple 证书流程
Android AABbundle 签名和商店流程最终 APK 签名责任不等同本地 APK
Apple IPA证书、provisioning 与代码签名重签和 entitlements不使用 APK scheme 术语
Native 库随容器签名覆盖处理后容器如何签名不把 build ID 当签名
测试包测试身份与生产差异不继承生产结论
验签回执工具、平台和候选是否绑定当前字节不证明业务安全

用本地校验器检查答卷证据完整性

下面的 Python 脚本读取 JSON 答卷,要求每个 claim 包含 id、statement、evidence_type、artifact_sha256、valid_until、boundary 和 reviewer。它校验摘要格式、日期、允许的证据类型、重复 id 与空字段,并把过期或证据类型为 declaration-only 的项标为阻塞。

脚本不判断供应商声明真假,也不下载报告或验证签名;这些动作需要买方信任策略和真实附件。它的作用是防止内容完整的营销段落因为缺少候选、边界和责任人而进入评审。生产流程还应校验证据文件摘要、attestation subject、签发者和候选实际身份。

答卷不得包含私钥、令牌、客户源代码或内部地址。附件可存放在受控系统,问卷只保存不可变摘要和访问索引。校验失败应返回具体 claim 和字段,供应商只补缺失字段或替换证据,不需要重写整份答卷,便于保留修订历史。

检查加固供应商答卷的候选、证据、有效期和边界
import datetime as dt
import json
import re
import sys
from pathlib import Path

if len(sys.argv) != 2:
    raise SystemExit('usage: validate_vendor_answers.py questionnaire.json')
input_path = Path(sys.argv[1])
if not input_path.is_file():
    raise SystemExit('questionnaire file is missing')
data = json.loads(input_path.read_text(encoding='utf-8'))
claims = data.get('claims')
if not isinstance(claims, list) or not claims:
    raise SystemExit('claims array is missing')
allowed_types = {'static-report', 'device-receipt', 'provenance', 'attestation', 'signature-receipt', 'declaration-only'}
digest_pattern = re.compile(r'^[a-f0-9]{64}$')
today = dt.date.today()
seen = set()
blocked = []
for index, claim in enumerate(claims):
    claim_id = str(claim.get('id', '')).strip()
    if not claim_id or claim_id in seen:
        raise SystemExit(f'invalid claim id at index {index}')
    seen.add(claim_id)
    for field in ('statement', 'evidence_type', 'artifact_sha256', 'valid_until', 'boundary', 'reviewer'):
        if not isinstance(claim.get(field), str) or not claim[field].strip():
            raise SystemExit(f'{claim_id}: missing {field}')
    if claim['evidence_type'] not in allowed_types:
        raise SystemExit(f'{claim_id}: unsupported evidence type')
    if not digest_pattern.fullmatch(claim['artifact_sha256'].lower()):
        raise SystemExit(f'{claim_id}: invalid artifact digest')
    try:
        valid_until = dt.date.fromisoformat(claim['valid_until'])
    except ValueError:
        raise SystemExit(f'{claim_id}: invalid validity date')
    reasons = []
    if valid_until < today:
        reasons.append('evidence-expired')
    if claim['evidence_type'] == 'declaration-only':
        reasons.append('no-independent-evidence')
    if reasons:
        blocked.append({'id': claim_id, 'reasons': reasons})
result = {'claim_count': len(claims), 'blocked_count': len(blocked), 'blocked': blocked, 'status': 'pass' if not blocked else 'blocked'}
print(json.dumps(result, ensure_ascii=False, indent=2))

第六组问题写清限制、到期和争议处理

每份证据都要有适用平台、候选、配置、设备范围和有效期。Android 或 iOS 大版本、NDK、Xcode、签名流程、加固工具、业务依赖或候选摘要变化时,哪些证据必须重验应预先约定。写永久有效会把历史测试错误扩张到未来环境。

合同验收应按 claim 列出 required evidence、通过标准、允许限制、阻塞条件和修复时限。一个能力阻塞不应被其他项平均成总体合格;可接受限制也必须由买方明确批准,并说明影响范围和到期日期。供应商不能用保密、行业惯例或客户很多替代当前候选证据。

准备采购评估时,可提交候选和配置摘要、保护边界、设备与场景矩阵、原始测试回执、provenance、attestation、平台签名证据、限制清单和责任人。申请入口由御盾中央平台统一承接。没有真实附件和复核结果时,只能登记待验证,不能写供应商已通过、攻击已阻断或兼容性已确认。

事实依据与适用边界

以下内容区分官方事实、本文工程判断和不能外推的范围,避免把设计建议写成未经验证的产品结论。

本文判断事实或工程依据适用限制
移动端抗篡改与抗逆向属于纵深防御控制。OWASP MASVS-RESILIENCE 给出移动端韧性控制的验证方向。控制目录不证明当前候选已经实施控制或达到任何防护强度。
安全发布需要保留来源、构建、验证和变更证据。NIST SP 800-218 SSDF 将安全软件开发与供应链风险纳入组织实践。组织级框架不定义某个加固产品的功能、等级或采购通过结果。
构建证明应绑定产物主体、构建者、构建类型、参数和依赖材料。SLSA Provenance v1.1 定义构建 provenance 的字段和语义。provenance 只证明记录的构建过程,不单独证明运行时安全和兼容。
供应链声明应把产物摘要和有类型的负载绑定。in-toto Attestation Statement v1 定义 subject、predicateType 和 predicate 结构。格式正确不保证内容真实,仍需可信签发者、签名和门禁验证。
Android 使用应用签名建立更新身份,并有不同签名方案覆盖范围。AOSP app signing 说明 Android 应用签名和 APK 签名方案。签名有效只证明覆盖范围内完整性和签名者身份,不证明业务代码安全。
Apple 平台通过代码签名、证书和运行验证建立 App 身份。Apple app code signing process 说明 Apple 应用代码签名流程。Apple 签名链不能与 Android APK 签名方案混为同一证据。
供应商每项能力声明都应绑定候选、证据、有效期、限制和复核人。工程判断:缺少这些字段时,买方无法确认报告对象、适用范围和责任。字段完整只允许进入复核,不自动证明声明内容真实。
供应商比较不能用无数据的排名替代逐项证据门禁。工程判断:术语数量、承诺强度和材料篇幅都不能替代当前候选的可复核事实。证据门禁帮助采购决策,但最终风险接受仍由买方结合业务场景决定。

工程常见问题

供应商提供客户名单和案例,能否替代当前候选测试?

不能。其他客户的应用、配置、设备和业务路径不同,应要求当前候选摘要绑定的保护、兼容和签名回执。

加固报告写明功能已开启,是否就是保护有效?

不是。配置存在属于静态证据,还需说明保护对象、运行边界、测试方法、失败条件和同一候选的动态回执。

设备兼容通过率很高,为什么仍要看失败明细?

总体比例可能掩盖关键设备和业务路径,也可能把未执行项放进分母。失败明细才能复现问题并判断影响范围。

有 SLSA provenance 是否就能证明加固服务安全?

不能。先核对 subject 和签发者;它证明记录的构建过程,不替代保护强度、漏洞、运行兼容和业务测试。

Android 和 iOS 能否共用一份签名验收表?

可以共用采购框架,但平台字段和验证方法必须分开。APK 签名方案与 Apple 证书、provisioning、entitlements 不能混用。

申请软件加固供应商证据评估要准备什么?

准备候选与配置摘要、保护边界、兼容矩阵、测试回执、provenance、attestation、平台签名证据、限制和责任人,再通过御盾中央平台提交。

想用自己的 App 验证?

提交候选包、目标系统和关键业务路径,申请御盾 PoC 与兼容性评估。

继续阅读: 御盾 VMP 接入前准备清单