3. 签名链路定义与场景

在多租户微服务架构中,数字签名不再是一次性、端到端的操作,而是形成了一条贯穿多个服务节点的签名链路。本章将明确定义签名链路的核心概念,解析数字签名在微服务间的传递流程与验证链,并给出多租户场景下的典型拓扑结构。

3.1 签名链路的基本定义

签名链路是指一个业务请求从入口网关开始,经过多个微服务节点,在每个节点上依次进行签名验证、上下文传递、以及可能的重签名或附加签名,最终到达目标服务或返回客户端的完整路径。

签名链路区别于普通请求链路的关键特征:

特征 普通请求链路 签名链路
数据完整性 依赖传输层 TLS 应用层数字签名 + TLS 双重保障
身份绑定 仅验证服务身份(mTLS) 验证调用方租户身份 + 用户身份 + 服务身份
防篡改粒度 传输中数据包 请求体 + 关键头部 + 时间戳 + 租户上下文
跨服务传递 透传 HTTP 头部 透传签名载荷 + 签名值 + 证书链
审计追溯 依赖日志聚合 签名链本身提供不可抵赖的审计证据
关键认知: 签名链路不是对 TLS 的替代,而是在应用层构建的、与租户身份绑定的信任传递链。TLS 保证通道安全,签名链路保证内容可信与租户隔离。

3.2 数字签名在微服务间的传递流程

一个完整的签名传递流程包含以下步骤,以 Istio Sidecar 代理模式为背景:

  1. 客户端签名:客户端(或入口网关)使用租户私钥对请求体 + 租户 ID + 时间戳 + 随机数进行签名,生成签名值 sig_client,并附加在请求头部。
  2. Sidecar 拦截与验证:Istio Sidecar(Envoy)通过自定义 Filter 拦截请求,提取签名头部,调用验证服务或本地公钥缓存验证 sig_client。
  3. 上下文注入:验证通过后,Sidecar 将验证结果(租户 ID、签名时间、签名算法)注入到请求的 x-signature-context 头部,供下游服务使用。
  4. 服务间转发:服务 A 处理完业务逻辑后,将原始签名载荷 + 自身签名(sig_service_a)附加到请求中,转发给服务 B。
  5. 递归验证:服务 B 的 Sidecar 验证 sig_client 和 sig_service_a,形成签名链的累积验证。
  6. 最终验证:目标服务收到请求时,可获取完整的签名链列表,进行端到端的完整性校验。
传递流程要点:
  • 每个服务节点既验证上游签名,也附加自身签名,形成链式信任。
  • 签名载荷中必须包含租户 ID,确保多租户场景下的隔离性。
  • 时间戳和随机数用于防止重放攻击。

3.3 签名验证链的结构

签名验证链是一个有序的签名列表,每个元素包含签名者身份、签名值、签名时间、被签名数据摘要。验证链的典型结构如下:

签名验证链 (Signature Chain)
├── 节点 1: 客户端 (租户 A)
│   ├── 签名算法: ECDSA-P256
│   ├── 签名时间: 2025-01-15T10:30:00Z
│   ├── 签名值: sig_client_base64
│   └── 被签名数据: body_hash + tenant_id + timestamp + nonce
├── 节点 2: 服务 A (gateway-svc)
│   ├── 签名算法: Ed25519
│   ├── 签名时间: 2025-01-15T10:30:01Z
│   ├── 签名值: sig_service_a_base64
│   └── 被签名数据: sig_client + body_hash + tenant_id
└── 节点 3: 服务 B (order-svc)
    ├── 签名算法: Ed25519
    ├── 签名时间: 2025-01-15T10:30:02Z
    ├── 签名值: sig_service_b_base64
    └── 被签名数据: sig_service_a + body_hash + tenant_id

验证链的验证规则:

  • 顺序验证:从链头开始,依次验证每个签名,前一个签名验证通过后才能验证下一个。
  • 数据完整性:每个签名都包含对前一个签名值的摘要,形成哈希链,任何中间篡改都会导致后续验证失败。
  • 租户一致性:所有签名中的 tenant_id 必须一致,否则视为跨租户攻击。
  • 时间窗口:相邻签名的时间差不能超过配置阈值(默认 5 秒),防止签名被延迟重放。

3.4 多租户签名链路的典型拓扑

在多租户环境中,签名链路需要同时处理租户隔离和服务共享的矛盾。以下给出两种典型拓扑:

3.4.1 集中式验证拓扑

所有签名验证集中在一个专用的签名验证服务(SVS)中完成,业务服务只负责透传签名载荷。这种拓扑适用于租户数量较少、对延迟不敏感的场景。

集中式签名验证拓扑 客户端 租户 A 入口网关 Istio Ingress 签名验证服务 SVS 服务 A 订单服务 服务 B 支付服务 说明: 所有签名验证请求统一发送到 SVS,SVS 返回验证结果。 业务服务不直接处理签名逻辑,降低耦合度,但 SVS 可能成为性能瓶颈。

3.4.2 分布式验证拓扑

每个服务的 Sidecar 代理本地完成签名验证,验证结果通过请求头部透传。这种拓扑适用于租户数量多、对延迟敏感的场景,也是 Istio 多租户签名链路的主流方案。

分布式签名验证拓扑(Istio Sidecar 模式) 客户端 Sidecar (验证) 入口网关 Sidecar (验证) 服务 A Sidecar (验证) 服务 B 公钥分发服务 (PKI) 说明: 1. 每个服务的 Sidecar 独立完成签名验证,验证结果写入 x-signature-context 头部。 2. 公钥由 PKI 服务统一分发,Sidecar 定期拉取并缓存,减少验证延迟。 3. 签名链在请求头部中累积传递,目标服务可获取完整的验证链进行审计。 4. 优势:无单点瓶颈,验证延迟低,适合大规模多租户场景。

3.5 拓扑对比与选型建议

对比维度 集中式验证拓扑 分布式验证拓扑
验证延迟 高(每次验证需 RPC 调用 SVS) 低(本地验证,缓存公钥)
单点瓶颈 SVS 可能成为瓶颈 无单点,水平扩展
租户扩展性 受限于 SVS 性能 随服务实例数线性扩展
运维复杂度 低(集中管理签名策略) 中(需管理 Sidecar 配置与公钥分发)
审计追溯 SVS 日志集中 签名链头部自带审计信息
Istio 集成度 需额外部署 SVS 原生集成,通过 Envoy Filter 实现
选型建议:
  • 租户数量 < 100、对延迟不敏感、团队运维能力有限 → 优先选择集中式拓扑。
  • 租户数量 > 1000、要求低延迟(P99 < 5ms)、已有 Istio 基础设施 → 优先选择分布式拓扑。
  • 中间规模(100~1000 租户)→ 可采用混合模式:关键路径分布式验证,非关键路径集中验证。

3.6 签名链路中的关键头部设计

在 Istio 环境下,签名链路的上下文通过 HTTP 头部传递。以下是一组推荐的头部设计:

头部名称 类型 说明 示例值
x-signature-value 请求 当前节点的签名值(Base64 编码) MEUCIQD...
x-signature-algorithm 请求 签名算法标识 ECDSA-P256
x-signature-timestamp 请求 签名生成时间(Unix 毫秒时间戳) 1736922600000
x-signature-chain 请求 累积的签名链(JSON 数组,每个元素包含签名者、签名值、时间戳) [{"signer":"client","sig":"...","ts":...},...]
x-signature-context 请求 验证结果上下文(由 Sidecar 注入,包含租户 ID、验证状态、签名者身份) tenant_id=tenant-a;verified=true;signer=gateway
x-signature-nonce 请求 防重放随机数 a1b2c3d4e5f6
头部传递规则:
  • x-signature-value 和 x-signature-algorithm 在每个服务节点被替换为当前节点的签名。
  • x-signature-chain 是累积的,每个节点在尾部追加自己的签名信息。
  • x-signature-context 由 Sidecar 注入,业务服务只读不写。
  • 所有签名头部必须包含在 Istio 的 request_headers_to_propagate 列表中,确保跨服务透传。