先看结论与判断条件

  • 只校验.tflite 或.onnx 文件摘要会遗漏元数据附带的标签、归一化参数和外部文件,形成受攻击面。
  • LiteRT FlatBuffer 元数据可携带输入描述和关联文件,但运行时不会自动校验其完整性,必须纳入清单。
  • ONNX Runtime Mobile 缺少内置模型签名和防回滚能力,需外部机制保证算子库与执行提供程序未被替换。
  • TUF 规范中的签名、版本号与一致快照验证能够识别回滚和混搭风险,但仅靠更新框架无法覆盖业务层授权。
  • SLSA 和 in-toto 构建证明可以锁定产物构建过程,证明不能代替设备侧实时校验模型文件摘要。
  • 预处理配置或 tokenizer 的篡改不会改变模型文件摘要,但资料未量化其对推理输出或精度的具体影响程度。
  • 版本耦合治理须在清单中记录模型与算子库的最低版本关系;资料未说明加载时需核对兼容性矩阵,也未证明跨设备行为差异。
  • 校验失败应采取阻断或降级策略;资料未证明静默忽略会导致全部治理措施失效。

模型资产的表面完整性与实际缺口

移动端应用可以用 APK 签名验证包内文件,但动态下载到应用数据目录的模型和元数据需要额外的来源与摘要校验。评审时先列出每个资产的交付位置和信任根,再确认加载代码是否逐项核对;不能只看主模型文件存在就假定整套推理输入完整。

更深一层的问题是,即使设备对模型文件做了哈希校验,也只覆盖了主文件。LiteRT 模型内嵌的 metadata 包含输入归一化参数、标签文件引用等关键信息,它们可能在模型分发后被独立替换。ONNX 模型则依赖外部算子实现库,如果运行时包体中的共享库被篡改,模型文件自身依旧干净,校验也不会失败,攻击者可以制造看似合法、实则异常的推理环境。

模型、预处理代码、算子库和运行时可能分别更新。若兼容关系只靠人工记忆,某次发布就可能遗漏联动检查,出现组件各自完整、组合行为却变化的情况。清单应记录经过验证的版本组合,并由回归样本确认输出,而不是把摘要校验当成兼容性证明。

  • 确认模型加载路径覆盖 APK 内置、Asset、文件系统和网络下载所有来源
  • 对每个来源的模型文件单独计算摘要,并与可信渠道提供的预期值比对
  • 检查是否仅校验了主模型文件而放过元数据和关联外部文件
  • 记录模型所依赖的运行环境版本号,并在清单中声明版本耦合要求

应纳入治理的五类资产

完整的模型资产清单应包含五类实体。首先是模型主文件,比如.tflite 或.onnx 序列化文件,这是推理的直接载体。第二类是元数据块及关联文件,LiteRT metadata 内可引用词汇表、标签文件,它们对正确解析输入输出至关重要。第三类是算子实现库,如 LiteRT delegate 共享库或 ONNX Runtime 的 Execution Provider 动态库。第四类是预处理与后处理配置,例如归一化均值、标准差、tokenize 规则或后处理阈值,即便它们存放在 JSON 或代码常量中,一旦被篡改也会破坏推理语义。

第五类是版本耦合元信息,它描述模型依赖的运行时、算子库、配置文件的最低版本范围。缺少这类元信息,设备无法判断升级后的模型是否能与现有算子集协同工作。反之,如果只校验前四类资产但不记录它们之间的版本关联,清单校验仍会被混搭攻击绕过:攻击者可组合旧版模型、新版预处理和旧版算子库,所有文件摘要都有效,但组合起来却产生错误结果。

治理起点是生成一份涵盖这五类的结构化清单,并对其签名或附加可信摘要。清单格式应可机读,支持自动化校验。构建流水线或安全运营平台应能根据清单自动提取每个资产的预期哈希值,并写入分发元数据。任何一类资产的缺失或摘要不一致都应导致完整性验证失败,不能区别对待,必须建立统一的阻断或降级机制来响应此类异常。

模型资产完整性覆盖清单示例
资产类型典型文件/载体检查动作失败影响
模型主文件model.tflite, model.onnx计算文件哈希并与清单比对推理模块直接失效或被恶意控制
元数据与关联文件FlatBuffer metadata、labels.txt、vocab.txt解析 metadata 提取关联文件路径,分别验证哈希分类标签错乱、分词结果偏移
算子实现库libdelegate.so、libonnxruntime.so、自定义 kernel验证共享库哈希及导出的符号版本模型无法加载或静默精度下降
预处理/后处理配置normalize_config.json、tokenizer_config.json配置内容哈希校验,注意转义和编码一致性输入数据量化错误,预测结果异常
版本耦合描述compatibility_info.yaml 或 manifest 内字段对比清单中声明的最低版本与运行时实际版本模型可加载但输出错误,难以复现

LiteRT 中的元数据解析与关联文件校验

根据 LiteRT 官方文档,模型元数据可携带输入输出张量描述、归一化参数、标签文件等信息,并以 FlatBuffer 结构内嵌或引用外部文件。这一设计原本是为了让推理管道能自动适配输入格式,但在安全视角下它引入了依赖关系:模型文件字节本身并不包含 label.txt 或 vocab.txt 的完整内容,校验模型 SHA‑256 无法察觉这些外部文件的变化。

如果攻击者或错误的分发流程替换了 labels.txt,而模型文件完好,分类器可能在特定类别上持续输出错误标签,而所有常规监控只关注模型文件摘要,这就形成一个持久且隐蔽的攻击面。类似风险也存在于归一化参数:若均值和标准差被微小幅度修改,在量化推理中可能造成较大输出偏差,但同样不会触发模型文件校验。

工程判断:可通过 TensorFlow Lite Support Library 或 flatc 工具在构建阶段解析 metadata,列出所有关联的外部文件路径和预期大小,并将其加入资产清单。设备侧不仅要核对模型文件摘要,还应依据清单逐一验证这些关联文件的哈希值。如果 metadata 自身包含内嵌参数,也需明确其预期哈希或纳入 collateral 文件进行整体签名,防止 metadata 被局部重写。

  • 使用 flatc 或 TFLite 支持库提取 metadata 中的 associated files 列表
  • 对每个关联文件计算 SHA‑256,并与清单中记录值比对
  • 验证 metadata 自身字节段的哈希,确保内嵌参数未被修改
  • 加载模型前执行以上检查,失败则阻止推理管道启动

ONNX Runtime Mobile 的算子依赖与包体约束

ONNX Runtime Mobile 在设备端装载 ONNX 模型,其执行能力直接受编译时包含的算子 kernel 和可选的 Execution Provider 限制。资料明确指出,运行时支持不提供内置的模型签名、授权或防回滚能力。因此,攻击者可以替换整个 onnxruntime 动态库,裁剪某些算子,使模型回退到参考实现甚至直接失败,而检查模型文件本身并不会发现该风险。

治理这类风险需要将算子实现库视为完整性保护对象。在构建阶段,应记录模型所需的算子集合以及对应的最低 ORT 版本和 Provider 要求,写入清单。设备端在初始化推理引擎前,不仅要核对.onnx 文件摘要,还应验证 libonnxruntime.so 或相应 delegate 库的摘要,并对比清单中的算子要求与运行时实际支持的算子集合。

只校验模型文件时,无法得知当前运行时是否仍包含模型需要的算子,也无法确认是否进入了回退路径。ONNX 移动端部署应把算子集合或运行时包版本写入资产清单,加载后再记录执行提供程序与输出回归结果;摘要正确只说明文件未变,不说明组合性能和精度符合预期。

LiteRT 与 ONNX 在完整性治理中的对比
维度LiteRTONNX治理要求
元数据FlatBuffer metadata 可嵌入参数或引用文件ONNX 有 model metadata 字段,但缺乏关联文件标准化机制均需将元数据和引用文件摘要纳入清单
算子依赖委托 delegate 可引入外部共享库依赖编译时内置 kernel 或可选的 execution provider必须校验算子库文件完整性并记录算子需求版本
运行时委托GPU、NNAPI 等 delegate 可独立更新通过 Execution Provider 扩展,同样可能独立分发委托/Provider 库需作为独立资产被覆盖
版本耦合元数据可携带所需 delegate 版本信息ONNX opset 版本隐含算子需求,但无运行时版本绑定应在清单中显式声明版本关系并在加载时核对

更新分发时的回滚、冻结与混搭风险

TUF(The Update Framework)规范要求更新客户端验证目标文件的签名、版本、过期时间,并执行一致快照检查。这一框架可直接用于模型 OTA 分发:若只用普通 HTTPS 下发模型但未实施版本验证,攻击者可拦截更新并回滚到含有已知漏洞或后门的旧模型,而客户端却认为是合法更新,导致安全风险长期潜伏。

在 AI 模型场景中,回滚攻击可能更具欺骗性。旧模型可能与当前预处理逻辑、后处理阈值不兼容,其结果在业务上不可接受,但如果没有版本耦合校验,App 无法分辨这种不兼容。同样,混搭攻击中攻击者可组合新版模型、旧版预处理配置和旧算子库,所有单独文件的签名都可验证通过,但三者组合却构成一个错误推理管道。

应用 TUF 时,需要针对模型资产设计角色和元数据层次,将模型文件、关联配置、算子库和兼容性信息分别定义为独立目标或 unified bundle。一致快照可防止客户端同时看到新旧元数据,但前提是服务端严格遵循规范生成和分发这些元数据。工程判断:必须为每个目标分配单调递增的版本号,并将该版本号与 App 侧的兼容性矩阵绑定。

构建证明与供应链签名的适用边界

SLSA Provenance v1.1 和 in‑toto Attestation Statement v1 提供了将模型产物的构建过程与产物摘要绑定的标准方式。构建证明可记录源码仓库、构建环境参数、依赖材料以及最终产物的 SHA‑256,为发布管道的准入控制提供可验证的来源追溯。这有助于阻断构建流水线内部的投毒或误打包,但不能替代设备运行时的完整性检查。

依据 in-toto 资料,证明声明将产物摘要与带类型的声明载荷绑定,防止声明与实际包不匹配,但声明格式本身不保证声明内容的真实性,仍需可信签名者和门禁核验。同理,SLSA provenance 只证明记录的构建过程,不能单独证明当前设备上加载的模型就是构建证明中所描述的那个文件,因为设备侧文件可能在传输后或安装后被替换。

实际工程中,构建证明应作为资产清单生成的一部分,将预期摘要集成到 TUF 或自有分发元数据中。设备侧使用存储在安全区域(如 Android Keystore)的公钥,验证资产清单的签名,然后依据清单中的摘要逐项核对文件。若设备不支持硬件信任根,签名验证的可靠性会降低,但仍优于完全忽略构建证明的做法,需结合多层防御策略。

清单生成与摘要验证的自动诊断代码

下面的 Bash 脚本读取 manifest 中的 SHA-256 和相对文件名,逐项核对资产目录。文件缺失或摘要不符时返回非零状态并打印具体条目,可直接用于 CI 的产物检查。

清单采用两列文本:第一列是 SHA-256,第二列是相对文件名;空行和以 # 开头的注释会被跳过。它只回答“文件内容是否与清单一致”,版本兼容、算子依赖和运行输出仍由兼容矩阵与设备回归检查。

在移动端生产环境中,应进一步对 manifest 文件本身做签名保护。如果 manifest 可以被改写,校验将失去意义。工程判断:可将 manifest 存放在可信位置(如 APK 内部资源,已被 APK 签名涵盖),或通过 TUF 取得可信的 manifest。脚本本身不应包含敏感逻辑,仅作为执行校验的工具存在。

模型资产清单完整性验证脚本
#!/usr/bin/env bash
set -euo pipefail
# 验证模型资产完整性的安全诊断脚本,不执行任何破坏性操作

MODEL_DIR="${1:?请提供模型资产目录作为第一个参数}"
MANIFEST="$MODEL_DIR/manifest.txt"

if [ ! -f "$MANIFEST" ]; then
  echo "错误:找不到清单文件 $MANIFEST" >&2
  exit 1
fi

# 初始化错误数组
errors=()

# 逐行读取清单,跳过注释和空行
while IFS= read -r line; do
  [[ "$line" =~ ^# ]] && continue
  [[ -z "$line" ]] && continue
  expected_sha=$(echo "$line" | awk '{print $1}')
  file_path=$(echo "$line" | awk '{print $2}')
  
  if [ ! -f "$MODEL_DIR/$file_path" ]; then
    errors+=("缺失文件:$file_path")
    continue
  fi

  # 计算实际哈希值,仅保留十六进制部分
  actual_sha=$(sha256sum "$MODEL_DIR/$file_path" | cut -d' ' -f1)
  if [ "$expected_sha" != "$actual_sha" ]; then
    errors+=("哈希不匹配:$file_path")
  fi
done < "$MANIFEST"

# 汇总错误并输出
if [ ${#errors[@]} -gt 0 ]; then
  for err in "${errors[@]}"; do
    echo "错误:$err" >&2
  done
  exit 1
fi

echo "所有模型资产验证通过。"

工程实施建议与失败处理策略

清单分发通道的签名和防回滚容易被忽略。清单随 APK 发布时可由 APK 签名覆盖;动态模型使用的清单则需要独立验证签名、版本与过期时间。工程判断:可借鉴 TUF 的签名元数据设计,并保留一个随应用发布的最低可信基线;具体信任根仍由项目更新架构决定。

校验失败的响应策略不能一概而论。对于运行在安全敏感场景的模型,任何资产不匹配都应立即阻止推理,并通知监控系统。对于内容推荐等容忍度稍高的场景,可回退到内置的、经过同等完整性校验的兜底模型,确保服务不中断。无论何种策略,严禁静默吞咽错误或仅打出日志警告,必须有明确的动作响应。

版本耦合治理建议在设备端维护一个轻量级兼容性矩阵,矩阵数据由 CI 在构建时填入资产清单。加载模型前,比较清单中声明的算子库、预处理配置和运行时版本与设备当前环境,若任何一项低于要求,则视为完整性失败或按预定义回退路径处理。矩阵应覆盖回滚场景:允许加载版本不低于已知安全基线的旧组合,但禁止任何未经验证的跨版本拼接。

模型资产完整性治理实施步骤
步骤涉及资产执行工具/机制失败处理
生成资产清单模型、元数据、算子库、预处理配置、版本信息构建脚本 + flatc / ORT 工具清单生成失败则终止构建
签名与分发清单清单文件及签名元数据TUF 仓库 / 应用内资源签名无效或过期则阻止客户端下载
设备侧逐项校验清单中列出的所有文件类似上文 Bash 脚本或类似逻辑任一不匹配则进入失败响应流程
失败响应与回退当前组合的兜底模型兼容性矩阵 + 预置模型包降级到已校验兜底模型,禁止静默忽略

事实依据与适用边界

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

本文判断事实或工程依据适用限制
LiteRT 在端侧加载模型并通过不同 delegate 执行推理。Google AI Edge LiteRT运行时会使用模型内容,磁盘加密不能消除内存中可用表示。
模型元数据可携带输入输出描述、归一化参数、标签和关联文件。LiteRT model metadata只校验主模型摘要会遗漏 tokenizer、标签与预处理配置。
ONNX Runtime Mobile 在 Android/iOS 装载模型,并受算子、包体和执行提供程序约束。ONNX Runtime Mobile运行时支持不提供模型签名、授权或防回滚能力。
更新客户端应验证签名、版本、过期时间和一致快照,以识别回滚、冻结和混搭风险。The Update Framework specificationTUF 是更新框架,不直接规定移动端模型或 APK 的业务授权策略。
构建证明应绑定产物主体、构建者、构建类型、外部参数与依赖材料。SLSA Provenance v1.1provenance 只能证明记录的构建过程,不能单独证明运行时安全性。
供应链证明应把产物摘要与有类型的声明负载绑定,避免报告与候选包错配。in-toto Attestation Statement v1声明格式不保证声明内容真实,仍需可信签名者和门禁核验。
发布判断应同时记录构建产物、配置版本与验证环境。工程判断这是一项审计方法,不代表具体项目已经通过验证。
完整性异常应在进入发布流程前失败关闭,并保留可复核的诊断记录。工程判断实际阻断策略仍需结合业务风险和项目测试证据确定。

工程常见问题

如何从 LiteRT 模型中提取元数据所引用的关联文件列表?

可以使用 TensorFlow Lite Support Library 或 flatc 命令行工具解析 FlatBuffer 结构,读取 metadata 段中的 AssociatedFiles 字段。提取出的文件路径应被纳入资产清单并进行完整性校验。需要注意的是,若 metadata 自身已被篡改,提取结果可能被伪造,因此执行提取操作前必须已建立对 metadata 字节段的信任。

ONNX 模型缺少某些算子时,ONNX Runtime Mobile 会有什么行为?

根据 ONNX Runtime Mobile 的资料,如果所需的算子未在编译的 kernel 中注册,运行时会尝试查找可用的 substitute 或 reference kernel,其行为和性能取决于当前的 Execution Provider 配置。可能表现为加载失败、精度下降或速度变慢,而未必有明确的异常抛出。因此必须在清单中声明算子需求,并在加载前与运行时包比对。

TUF 框架能否直接用于模型资产的分发和防回滚?

TUF 规范提供了签名、一致快照和版本号等机制,可防止回滚和混搭攻击,但它是一个更新框架,不包含业务层的授权或兼容性判断。需要为模型产物设计合理的元数据层次,并为每个目标定义单调递增的版本号,再结合应用的兼容性矩阵才能发挥防护作用。

有了 SLSA 构建证明,是否还需要在设备上再计算一次模型摘要?

需要。SLSA 构建证明记录了模型是在何种环境下构建的,以及其预期摘要,但不保证设备上的文件仍是该摘要对应的产物。设备侧必须重新计算摘要并与绑定在构建证明(或资产清单)中的预期值比较,这属于运行时的完整性验证,二者缺一不可。

模型资产清单应该存放在哪里,如何保障其自身安全?

清单可以内置于 APK,由 APK 签名提供完整性保护;对于动态更新的模型,清单需通过安全通道下发,例如使用 TUF 元数据或 HTTPS + 数字签名。若清单自身被篡改,所有后续校验形同虚设,因此清单文件必须被视为安全关键资产,其分发链路的保护等级不可低于模型本身。

校验不通过时,应用应该直接崩溃还是回退?

这取决于业务安全等级。对于不可容忍错误结果的场景,比如医疗或工业安全,应直接阻断推理并上报。对于容许降级服务的场景,可回退到内置的且已经过同样完整性校验的兜底模型。无论哪种策略,都不能静默使用未通过校验的模型,因为那将使完整性治理完全失效。

想用自己的 App 验证?

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

继续阅读: 移动 AI 应用的运行时安全边界