<!-- title: 5G切换密钥链NH派生机制 -->
<!-- domain: security -->

# 5G切换密钥链NH派生机制：水平/垂直推演与前向安全全链拆解

> 本文聚焦 3GPP TS 33.501《Security architecture and procedures for the 5G system》第 6.9 节及附录 A，深入拆解 5G 系统在切换场景下接入层（AS）密钥的派生与刷新机制——即 **NH（Next Hop）密钥链、NCC（Next Hop Chaining Count）同步、水平/垂直推演** 这一套确保前向安全的核心机制。这是 5G 安全架构中最精妙、也最容易让协议开发工程师困惑的部分之一。

---

## 一、为什么要设计 NH 密钥链：前向安全的设计动机

在 4G/5G 这类分布式接入网架构中，gNB 是部署在物理上不可控环境（基站机房、铁塔）的网络实体，其被攻破或被物理获取的概率远高于核心网网元。如果一个 gNB 长期持有同一个接入层根密钥 **KgNB**，那么一旦该 gNB 被攻破，攻击者不仅可以解密当前用户的空口流量，还可能在用户切换到其他 gNB 后继续推演出后续的密钥，造成"密钥泄露一路向前蔓延"的灾难性后果。

为解决这一信任边界问题，3GPP 自 Rel-8 LTE（TS 33.401）起引入了 **NH（Next Hop）密钥链**机制，并在 5G（TS 33.501）中完整继承并增强。其核心思想可以一句话概括：

> **每发生一次切换，接入层密钥都要"向前推进一步"，且这种推进是不可逆的——一旦推进完成，旧的 gNB 即使用其持有的密钥，也无法反推出任何未来的密钥。**

这就是所谓的 **前向安全（Forward Security）**。与之配套的，是 **KAMF 只存在于 UE 和 AMF 两端**这一关键事实——NH 的派生必须依赖 KAMF，而 gNB 永远拿不到 KAMF，因此 gNB 无法自行推进密钥链，必须每次向 AMF"索取"下一跳密钥。这一不对称性正是整个机制的信任根基。

---

## 二、5G 密钥层级总览：从永久密钥 K 到 KgNB

要理解 NH 链，必须先看清 5G 完整的密钥派生层级。下图给出了从用户永久密钥 K 到空口各类业务密钥的完整链路（依据 TS 33.501 附录 A）：

```text
flowchart TD
    K["K（永久密钥，128/256 bit）<br/>存于 USIM 与 UDM/ARPF"]
    KAKM["5G AKA / EAP-AKA' 运行<br/>产生 CK, IK 或 CK', IK'"]
    K --> KAKM
    KAUSF["KAUSF<br/>FC=0x6A，输入 SN-name<br/>存于 UE 与 AUSF（附录 A.2）"]
    KAKM --> KAUSF
    KSEAF["KSEAF<br/>FC=0x6E，输入 SN-name<br/>存于 UE 与 SEAF/AMF（附录 A.3）"]
    KAUSF --> KSEAF
    KAMF["KAMF（接入与移动性根密钥）<br/>FC=0x6F，输入 SUPI + ABBA<br/>存于 UE 与 AMF（附录 A.4）"]
    KSEAF --> KAMF
    KgNB["KgNB（gNB 接入层根密钥）<br/>FC=0x6D，输入 PCI + ARFCN-DL<br/>存于 UE 与 gNB（附录 A.6）"]
    KAMF --> KgNB
    NH["NH（Next Hop 下一跳密钥）<br/>FC=0x6C，输入 KgNB 或前一 NH<br/>存于 UE 与 AMF（附录 A.7）"]
    KAMF --> NH
    sub 叶子密钥
    KRRCenc["KRRCenc / KRRCint<br/>RRC 加密 / 完整性"]
    KUPenc["KUPenc / KUPint<br/>用户面加密 / 完整性"]
    end
    KgNB --> 叶子密钥
    style KAMF fill:#fff3cd
    style NH fill:#d1ecf1
    style KgNB fill:#f8d7da
```

几个关键点必须强调：

1. **KAMF 是接入侧信任锚**：它由 KSEAF 派生，派生时混入了 **ABBA 参数**（Anti-Bidding-down Between Architectures），用于防止将安全级别"降级"到 EPS/4G 的攻击。
2. **KgNB 由 AMF 派生后下发给 gNB**：当 UE 从空闲态转为连接态（Initial Context Setup）时，AMF 用 KAMF 推演出 KgNB，通过 NGAP 接口下发给 gNB。
3. **NH 与 KgNB 同源但用途不同**：NH 是"备用"的下一跳密钥，平时不用，只在切换时启用；它的派生输入是"当前的 KgNB"或"上一个 NH"，形成一条单向链。

下表汇总了主链各密钥的派生参数（KDF 函数见附录 B.2，均基于 HMAC-SHA-256）：

| 密钥 | 派生自 | FC | 输入参数 P0 / P1 | 持有实体 | 对应章节 |
|------|--------|----|------------------|----------|----------|
| KAUSF | CK‖IK（或 CK'‖IK'） | 0x6A | SN-name | UE / AUSF | 附录 A.2 |
| KSEAF | KAUSF | 0x6E | SN-name | UE / SEAF(AMF) | 附录 A.3 |
| KAMF | KSEAF | 0x6F | SUPI / ABBA | UE / AMF | 附录 A.4 |
| KgNB | KAMF | 0x6D | PCI / ARFCN-DL | UE / gNB | 附录 A.6 |
| NH | KAMF | 0x6C | KgNB 或前一 NH | UE / AMF | 附录 A.7 |
| KgNB* | KgNB（水平）或 NH（垂直） | 0x6D | 目标 PCI / 目标 ARFCN-DL | UE / 目标 gNB | 附录 A.8 |

---

## 三、NH 密钥链的构造：一条只能向前走的单向链

NH 的构造是一条严格单向的链（TS 33.501 附录 A.7）：

```
NH_1 = KDF(KAMF,  FC=0x6C,  KgNB_initial)
NH_2 = KDF(KAMF,  FC=0x6C,  NH_1)
NH_3 = KDF(KAMF,  FC=0x6C,  NH_2)
...   （以此类推）
```

注意三个要点：

- **输入密钥是 KAMF，不是 KgNB**：这是 NH 链"不可被 gNB 自行推进"的根本原因。gNB 只有 KgNB，没有 KAMF，所以 gNB 算不出 NH_2、NH_3……。
- **每个 NH 只依赖前一个**：NH_3 = f(NH_2)，但已知 NH_3 不能反推 NH_2（HMAC 单向性），所以一旦链推进到 NH_3，持有 NH_1 的实体无法推出 NH_3。
- **NCC 是链的位置索引**：每个 NH 都关联一个 NCC（Next Hop Chaining Count），取值范围 **0~7**（3 bit）。NCC=0 表示当前活跃的是 KgNB 本身（即水平推演），NCC≥1 表示当前活跃密钥派生自 NH_{NCC}。

```mermaid
flowchart LR
    KAMF0["KAMF"]:::anchor
    KgNB0["KgNB<br/>(活跃, NCC=0)"]:::active
    NH1["NH_1 (NCC=1)"]:::nh
    NH2["NH_2 (NCC=2)"]:::nh
    NH3["NH_3 (NCC=3)"]:::nh
    KAMF0 --> KgNB0
    KAMF0 -->|"FC=0x6C"| NH1
    KAMF0 -->|"FC=0x6C"| NH2
    KAMF0 -->|"FC=0x6C"| NH3
    KgNB0 -.->|"水平推演<br/>下一跳"| NH1
    classDef anchor fill:#fff3cd,stroke:#856404
    classDef active fill:#f8d7da,stroke:#721c24
    classDef nh fill:#d1ecf1,stroke:#0c5460
```

UE 和 AMF 双方各自独立维护这条链与当前 NCC 值，并保持同步。同步的正确性，正是切换能否成功加解密的关键。

---

## 四、核心机制：切换中的水平推演与垂直推演

这是本文的核心。当 UE 发生切换时，目标 gNB 需要一个新的 KgNB*（即 KgNB 的下一跳）。派生 KgNB* 有两种方式（TS 33.501 第 6.9.2 节）：

### 4.1 水平推演（Horizontal Key Derivation）

```
KgNB* = KDF( KgNB_current,  FC=0x6D,  目标PCI,  目标ARFCN-DL )
```

- **输入是当前的 KgNB**，**NCC 保持不变**。
- 任何一次切换，源 gNB 都可以无条件做一次水平推演（因为它手里有 KgNB）。

### 4.2 垂直推演（Vertical Key Derivation）

```
KgNB* = KDF( NH,  FC=0x6D,  目标PCI,  目标ARFCN-DL )
```

- **输入是 NH（下一跳密钥）**，**NCC 加 1**。
- 垂直推演才能真正"推进"密钥链，实现前向安全。

### 4.3 关键规则：首次切换为何一定走水平？

根据 TS 33.501 第 6.9.2.1.1 节的明确规定：

> *"Since the AMF does not send the NH value to gNB/ng-eNB at the initial connection setup, the NH value associated with NCC=1 is not used for the first inter-gNB handover; horizontal key derivation is used for the first handover."*

也就是说，UE 初始建立安全上下文时，AMF **只下发 KgNB 给 gNB，不下发 NH**。因此第一次跨 gNB 切换时，源 gNB 手里只有 KgNB、没有 NH，只能做水平推演；待切换完成后，新的目标 gNB 通过 PATH SWITCH 流程向 AMF 索取到新的 (NH, NCC)，此后才具备垂直推演的能力。

这一设计是性能与安全的折中：避免在每次 Initial Context Setup 时就把 NH 链条预先生成并下发，减少信令开销；同时通过"先水平、后垂直"的递进，保证即使第一次切换是水平的，第二次起也能进入前向安全通道。

### 4.4 Xn 接口切换完整信令时序

下图是一次典型的 **Xn 接口跨 gNB 切换**，标注了密钥在每个消息中的流转（重点观察 NH/NCC/KgNB* 的传递）：

```mermaid
sequenceDiagram
    autonumber
    participant UE
    participant SG as 源 gNB<br/>(持有 KgNB, NCC=n)
    participant TG as 目标 gNB
    participant AMF

    Note over UE,AMF: 切换前：UE 与源 gNB 均持 KgNB；<br/>AMF 已预生成 NH（NCC=n+1）待用

    SG->>SG: ① 决定切换，判断是否持有<br/>来自 AMF 的 NH（NCC=n+1）
    alt 持有 NH（可垂直推演）
        SG->>SG: ② 垂直推演 KgNB* = KDF(NH, 目标PCI, ARFCN-DL)<br/>NCC = n+1
    else 无 NH（首次/链耗尽）
        SG->>SG: ② 水平推演 KgNB* = KDF(KgNB, 目标PCI, ARFCN-DL)<br/>NCC = n（不变）
    end

    SG->>TG: ③ XnAP HANDOVER REQUEST<br/>携带: KgNB*, NCC
    TG->>TG: ④ 由 KgNB* 派生 KRRCenc/int, KUPenc/int<br/>准备 AS 安全上下文
    TG->>SG: ⑤ XnAP HANDOVER REQUEST ACKNOWLEDGE

    SG->>UE: ⑥ RRC Reconfiguration (ReconfigurationWithSync)<br/>IE: nextHopChainingCount = NCC
    Note over UE: ⑦ UE 比对收到的 NCC：<br/>若 NCC == 本地 NCC → 水平推演<br/>若 NCC > 本地 NCC → 先推进 NH 链再垂直推演

    UE->>TG: ⑧ RRC ReconfigurationComplete<br/>用新的 KgNB* 派生密钥加密/完整性保护
    TG->>AMF: ⑨ NGAP PATH SWITCH REQUEST
    AMF->>TG: ⑩ PATH SWITCH REQUEST ACKNOWLEDGE<br/>⚠️ 关键：携带新的 (NH, NCC=n+2)<br/>供"下一次"切换垂直推演使用
    Note over TG: 目标 gNB 现已升格为新源 gNB<br/>具备垂直推演能力
```

整个流程中最容易被忽视、却最核心的是 **第 ⑩ 步**：AMF 在 PATH SWITCH REQUEST ACKNOWLEDGE 中，必须把"再下一跳"的 NH 与递增后的 NCC 下发给新 gNB。正是这一步，让密钥链能够在网络侧持续推进，而无需 UE 触发新一轮主认证。

### 4.5 UE 侧 NCC 同步决策流程

UE 在收到 ReconfigurationWithSync 后，依据 `nextHopChainingCount` 这一 RRC IE（见 TS 38.331）做如下决策：

```text
flowchart TD
    A[UE 收到切换命令<br/>nextHopChainingCount = NCC_recv] --> B{NCC_recv 是否等于<br/>本地当前 NCC?}
    B -->|是| C[水平推演<br/>KgNB* = KDF(KgNB, 目标PCI, ARFCN-DL)]
    B -->|否| D{NCC_recv 是否大于<br/>本地 NCC?}
    D -->|是| E[推进 NH 链<br/>重复 KDF(KAMF, NH) 直至 NCC 对齐]
    E --> F[垂直推演<br/>KgNB* = KDF(NH, 目标PCI, 目标ARFCN-DL)]
    D -->|否| G[❌ 异常：NCC 回退<br/>应为非法，触发安全失败]
    C --> H[更新本地 KgNB ← KgNB*<br/>更新本地 NCC ← NCC_recv]
    F --> H
    H --> I[激活新的 AS 安全上下文<br/>派生 KRRCenc/int, KUPenc/int]
```

这一同步逻辑保证了：**无论网络侧最终选择水平还是垂直，UE 都能仅凭一个 NCC 值就复现出与网络侧完全一致的 KgNB\***。这是整个机制能跨厂商互通的精髓所在——UE 不需要知道"网络用了哪条链路"，只需要看 NCC 是否前进。

---

## 五、N2 接口切换（经核心网）的密钥差异

当两个 gNB 之间没有 Xn 接口、或切换需要核心网参与时（N2 Handover，TS 23.502 第 4.9.1.3 节），密钥流转路径不同：

| 维度 | Xn 切换 | N2 切换 |
|------|---------|---------|
| 密钥派生主体 | 源 gNB 自行派生 KgNB* | AMF 派生 KgNB* 后下发 |
| NH 获取时机 | PATH SWITCH 之后 | 切换请求阶段即由 AMF 提供 |
| 首跳是否可垂直 | 通常水平（首次无 NH） | **首次即可垂直**（AMF 直接给 NH） |
| NCC 推进 | 源 gNB 决定 | AMF 决定并显式下发 |
| 信令路径 | UE↔gNB↔gNB | UE↔gNB↔AMF↔gNB |

N2 切换因为 AMF 全程参与，安全性更强（首次即可垂直推演），但信令时延更高。

---

## 六、水平 vs 垂直推演的本质对比

| 对比项 | 水平推演（Horizontal） | 垂直推演（Vertical） |
|--------|------------------------|----------------------|
| 派生输入密钥 | 当前 KgNB | NH（下一跳密钥） |
| NCC 变化 | 不变 | +1（推进） |
| 是否推进密钥链 | 否 | 是 |
| 前向安全贡献 | 弱（旧 gNB 仍可推一步） | 强（旧 gNB 无法再推） |
| 触发条件 | 首次切换 / gNB 无可用 NH | gNB 已持有 AMF 下发的 NH |
| 安全前提 | gNB 持有 KgNB 即可 | gNB 持有 NH（来自 AMF） |
| 设计意图 | 兜底，保证切换总能成功 | 常态，保证链不断推进 |

**一句话理解**：水平推演是"保险绳"，保证任何情况下切换不会因密钥问题失败；垂直推演是"主引擎"，才是真正兑现前向安全承诺的手段。一个设计良好的网络，应当在每次 PATH SWITCH 后让 gNB 尽快获得新 NH，从而在后续切换中优先采用垂直推演。

---

## 七、与 LTE KeNB/NH 机制的对比

5G 的 NH 机制脱胎于 4G（TS 33.401），但有几处关键演进：

| 对比项 | 4G（TS 33.401） | 5G（TS 33.501） |
|--------|-----------------|-----------------|
| 接入侧根密钥 | KASME → KeNB | KAMF → KgNB |
| 根密钥派生输入 | NAS Uplink COUNT | PCI + ARFCN-DL |
| NH 派生输入 | KASME | KAMF |
| 是否区分 NSA/SN | 否 | 是（引入 KRRCint 强制、KUPint 可选） |
| ABBA 防降级 | 无 | KAMF 派生混入 ABBA，防降至 EPS |
| 密钥长度 | 固定 256 bit 输出 | 支持 128/256 bit 算法区分 |
| 前向安全原理 | 相同（NH 链 + NCC） | 相同并强化 |

5G 相比 4G 最大的安全增强在于：**空口完整性保护从"可选"变为"强制"**（KRRCint 与 KNASint 对所有信令强制启用），并新增了用户面完整性保护密钥 KUPint，这与 NH 链的"防篡改切换命令"协同，使得攻击者即便重放或篡改 nextHopChainingCount，也无法绕过完整性校验。

---

## 八、实战：抓包如何识别这一流程

使用 Wireshark/TShark 分析 NGAP+RRC 抓包时，识别 NH/NCC 流转的关键点如下：

1. **Initial Context Setup（初始上下文建立）**：
   - 在 NGAP `INITIAL CONTEXT SETUP REQUEST` 中查找 `Security Key`（即 KgNB，256 bit）。
   - 此时**不应**出现 NH 字段——印证"首次不下发 NH"。

2. **Xn 切换**：
   - XnAP `HANDOVER REQUEST`：检查是否携带 `NR Encryption Algorithm`、`NR Integrity Protection Algorithm` 以及 NCC 相关安全上下文。
   - RRC `ReconfigurationWithSync` → `SecurityConfig`：定位 `nextHopChainingCount` IE（取值 0~7），这是判断 UE 走水平还是垂直的依据。

3. **PATH SWITCH**：
   - NGAP `PATH SWITCH REQUEST ACKNOWLEDGE`：应出现 AMF 下发的 **新 NH 与递增 NCC**。若多次 PATH SWITCH 后 NCC 始终不递增（始终为 0），说明垂直推演从未触发，疑似厂商实现保守或 NH 链未维护。

抓包实战命令示例（TShark）：

```bash
# 提取所有切换相关的安全上下文与 NCC
tshark -r handover.pcap -Y "ngap.procedureCode==46 || xnap.handoverRequest || rrc.nextHopChainingCount" \
  -T fields -e frame.number -e ngap.procedureCode -e rrc.nextHopChainingCount \
  -e xnap.id_NRCGI
```

---

## 九、常见故障点与排错思路

| 现象 | 可能根因 | 排查方向 |
|------|----------|----------|
| 切换后 UE 上下行均无法解密 | UE 与 gNB 推演的 KgNB* 不一致 | 核对 nextHopChainingCount 是否正确传递；UE 侧 NCC 是否同步 |
| NCC 回退告警 | 信令异常或重放攻击 | 检查 PATH SWITCH 序列；NCC 只能单调递增（绕回 0 除外） |
| 连续多次切换后密钥失效 | NH 链耗尽未及时续期 | 检查 AMF 是否在每次 PATH SWITCH 都下发新 NH |
| 仅首次切换后即安全失败 | gNB 误用垂直推演但无 NH | 确认首次切换应走水平推演 |
| 互操作（5G↔4G）切换失败 | ABBA / KDF 参数不匹配 | 核对 KAMF 派生的 ABBA 参数是否与对端一致 |

**黄金排错法则**：只要 UE 与网络侧的 KgNB* 出现哪怕 1 bit 差异，整个 AS 安全上下文就会失败。排错的第一步永远是"在 UE 侧和网络侧分别打印派生 KgNB\* 的全部 KDF 输入（KgNB 或 NH、目标 PCI、目标 ARFCN-DL、NCC），逐字节比对"。

---
## 常见问题

**Q1: 水平推演既然不能提供前向安全，为什么标准还要保留它？**
A: 水平推演是兜底机制。首次跨 gNB 切换时，源 gNB 还没从 AMF 拿到 NH，若不允许水平推演，切换将直接失败。它保证"切换总能成功"，再由垂直推演在后续逐步兑现前向安全。二者是"可用性"与"安全性"的互补。

**Q2: UE 怎么知道网络侧用了水平还是垂直？**
A: UE 不需要显式知道。它只需根据收到的 `nextHopChainingCount`（NCC）与本地 NCC 比较：相等则水平、变大则先推进 NH 链再垂直。一个 NCC 值就足以让 UE 复现出与网络一致的 KgNB*。

**Q3: 一个被攻破的 gNB 最坏能造成什么影响？**
A: 它能用持有的 KgNB 做一次水平推演，推导出紧随其后的下一跳 KgNB*（即"泄漏一步"）。但只要此后切换走了垂直推演，旧 gNB 因没有 KAMF 而无法继续推进 NH 链，密钥泄露即被"截断"。这正是前向安全把泄露范围限制在"最多落后一跳"的设计目标。

**Q4: NCC 只有 0~7，绕回怎么办？**
A: NCC 是 3 bit，到 7 后绕回 0 时，UE 与 AMF 会基于新的 KAMF（通常伴随一次新的主认证或 KAMF 刷新）重新建立 NH 链，避免链无限增长带来的存储与同步压力。这也意味着长时间不断切换的用户，会周期性地触发 KAMF 刷新。

**Q5: PDCP COUNT 快溢出时也要刷新密钥吗？**
A: 是的。当某个无线承载的 PDCP COUNT 即将回绕时（TS 33.501 第 6.9.3 节），gNB 会触发 **Key Refresh**：用专门的 KDF 输入重新派生 KgNB 及其子密钥，无需完整的切换或重新认证。这与切换密钥刷新是两套独立但互补的机制——前者防 COUNT 重用，后者防 gNB 长期持密。

---

## 参考来源

1. [3GPP TS 33.501 V18.10.0 — Security architecture and procedures for the 5G system](https://www.etsi.org/deliver/etsi_ts/133500_133599/133501/18.10.00_60/ts_133501v181000p.pdf) — 第 6.9 节（切换密钥派生）、第 6.9.2.1.1 节（首次切换水平推演规则）、附录 A.2~A.8（各级密钥 KDF 参数）
2. [3GPP TS 33.501 — 3GPP 规范门户](https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=3169) — 规范主页与版本索引
3. [NH (Next Hop key) — 3GPP Glossary | 3GPP Explorer](https://3gpp-explorer.com/glossary/nh/) — NH 密钥的定义、Rel-8 起源与前向安全原理说明
4. [5G AS 层密钥处理通用原则 — CSDN](https://blog.csdn.net/weixin_44710341/article/details/159929439) — KgNB*/NH 密钥链水平/垂直推演模型图解
5. [关于 5G Handover 中密钥派生的一些理解 — 博客园](https://www.cnblogs.com/machi12/p/16521057.html) — UE 侧垂直派生为何需先派生 NH 的深度解析（含 TS 33.501 Sec 6.9.2.1.1 原文引用）

---

> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
