3. 透明日志(Transparency Log)基础:Merkle树结构、日志审计、不可篡改性保证

透明日志(Transparency Log)是 Sigstore 信任链的“锚点”。它本质上是一个仅可追加(Append-Only)的公开账本,用于记录所有签名元数据(如镜像摘要、签名证书、OIDC 令牌)。通过将日志组织为 Merkle 树,任何客户端都可以在不下载全量日志的前提下,高效验证某条记录是否被正确包含,且日志无法被篡改或选择性删除。

3.1 Merkle 树结构:从叶子到根

Sigstore 使用的透明日志(Rekor)采用二进制 Merkle 树(Binary Merkle Tree)来组织记录。每条签名记录对应树中的一个叶子节点,叶子节点自底向上两两哈希,最终生成唯一的根哈希(Root Hash)。

核心特性: 根哈希是日志当前状态的“指纹”。只要根哈希不变,整棵树的完整性就得到保证。任何对叶子节点的修改都会导致根哈希不一致。
Merkle 树结构示意图 Leaf 1 Leaf 2 Leaf 3 Leaf 4 Hash(1+2) Hash(3+4) Root Hash 不可篡改保证 修改任一叶子 → 中间哈希变化 → 根哈希不匹配

3.2 日志审计:包含证明与一致性证明

透明日志提供两种核心审计能力,确保客户端可以独立验证日志的诚实性:

证明类型 用途 验证方式
包含证明
(Inclusion Proof)
验证某条记录确实存在于日志中 客户端从叶子节点出发,沿 Merkle 树路径计算到根哈希,与公开的根哈希比对
一致性证明
(Consistency Proof)
验证日志在两次快照之间没有发生回滚或重写 比较旧根哈希与新根哈希,检查 Merkle 树追加过程是否合法
冷启动场景提示: 在镜像供应链冷启动阶段,客户端首次接入时需下载当前日志的根哈希(约 32 字节),而非全量日志。后续每次验证仅需获取包含证明路径上的 O(log N) 个哈希值,极大降低带宽和存储开销。

3.3 不可篡改性保证:Checkpoint 与 Witness

透明日志的不可篡改性并非仅靠 Merkle 树结构实现,还需要结合 Checkpoint(检查点)和 Witness(见证者)机制:

  1. Checkpoint:日志服务器定期将当前根哈希、树大小、时间戳打包成签名结构,称为 Checkpoint。客户端可以缓存最近的 Checkpoint 作为信任锚点。
  2. Witness:一组独立运行的第三方服务,持续监控日志的追加行为。每个 Witness 对 Checkpoint 进行签名,形成“见证签名”。如果日志试图回滚或分叉,Witness 会检测到不一致并发出警报。
  3. Gossip 协议:Witness 之间通过 Gossip 协议交换 Checkpoint,确保所有参与者对日志状态达成共识,防止“只对部分节点展示不同日志”的 Split-View 攻击。
安全边界: 透明日志本身不加密记录内容,所有签名元数据公开可读。不可篡改性保证的是“记录一旦写入,无法删除或修改”,而非“记录内容保密”。在镜像供应链中,镜像摘要和签名证书均为公开信息,无需担心隐私泄露。

3.4 资源配额视角下的日志操作成本

从资源配额和冷启动削峰的角度,透明日志的 Merkle 树结构直接影响客户端验证的计算和网络开销:

操作 时间复杂度 网络传输量 冷启动影响
获取根哈希 O(1) 32 字节 极低,可缓存
包含证明验证 O(log N) ~1 KB(N=10⁶) 低,适合批量验证
一致性证明验证 O(log N) ~1 KB 低,仅在日志更新时触发
全量日志下载 O(N) GB 级 极高,应避免

在冷启动场景中,客户端应优先使用 包含证明 和 一致性证明,而非全量同步。通过缓存最近的 Checkpoint 和 Witness 签名,可以将每次镜像验证的网络开销控制在 KB 级别,实现真正的“削峰”。

透明日志审计流程 客户端 透明日志 Witness 请求包含证明 Checkpoint 签名 Gossip 交换 一致性验证 审计流程:客户端请求包含证明 → 日志返回 Merkle 路径 → 客户端本地计算根哈希 → 与 Witness 签名的 Checkpoint 比对

3.5 不可篡改性的数学基础

Merkle 树的不可篡改性建立在 抗碰撞哈希函数 的密码学假设之上。Sigstore 使用 SHA-256 作为哈希函数,其安全性满足:

  • 抗原像性:给定哈希值 H,无法找到原始输入 x 使得 H = SHA256(x)。
  • 抗第二原像性:给定输入 x,无法找到另一个输入 y ≠ x 使得 SHA256(x) = SHA256(y)。
  • 抗碰撞性:无法找到任意两个不同的输入 x 和 y 使得 SHA256(x) = SHA256(y)。

这意味着攻击者无法伪造一条记录使其哈希值与现有叶子节点相同,也无法构造一棵不同的 Merkle 树却产生相同的根哈希。任何篡改行为都会被客户端通过包含证明或一致性证明检测到。

冷启动削峰关键结论: 透明日志的 Merkle 树结构使得客户端可以在不信任日志服务器的情况下,以 O(log N) 的代价验证任意记录。在镜像供应链冷启动阶段,这一特性允许我们仅缓存根哈希和少量 Witness 签名,即可对成千上万个镜像签名进行批量验证,避免全量日志同步带来的网络和存储峰值。