<!-- title: 5G接入层KgNB密钥推演与NH链拆解 -->
<!-- domain: security -->

# 5G接入层KgNB密钥推演与NH链机制全链拆解

> 聚焦 3GPP TS 33.501 Annex A.9 / A.10 / A.11 与 Section 6.9.2 中接入层（AS）密钥在切换场景下的推演与前向安全机制，区别于已覆盖的"5G AKA认证与密钥推演"（NAS/认证层 KSEAF→KAMF）。本文专门拆解空口 RRC/UP 密钥 **KgNB** 的产生、**NH（Next Hop）/ NCC** 密钥链，以及水平/垂直推演如何在不同切换中保证密钥新鲜性与前向安全。

---

## 一、为什么AS密钥推演是5G安全的一个独立核心议题

很多工程师把"5G安全"等同于"5G AKA认证"。这其实只覆盖了**认证层**：USIM与UDM/ARPF持有的永久密钥 **K**，经 AKA 产生 CK/IK，在 AUSF 衍生 **K~AUSF~**，再到 SEAF 衍生 **K~SEAF~**，最终在 AMF 衍生 **K~AMF~**。至此，UE 与 AMF 共享了 NAS 层的锚密钥。

但用户面和控制面真正在**空口**（UE ↔ gNB）上传输时，加密/完整性保护用的是另一组密钥：**K~RRCint~、K~RRCenc~、K~UPint~、K~UPenc~**。这组密钥的根是 **KgNB**，由 K~AMF~ 推演而来。它们的设计难点不在"产生"，而在**移动性**：

- UE 每次切换到新 gNB，空口密钥必须更新，否则旧 gNB 仍可解密新 gNB 的流量；
- 更新的同时必须保证**前向安全**（forward security）：一个被攻破的 gNB，不能推算出它之后的切换所用的密钥；
- 整个过程还不能每次切换都回核心网要新密钥（否则时延和信令开销无法接受）。

这套矛盾正是 **NH（Next Hop）参数 + NCC（Next Hop Chaining Counter）+ 水平/垂直推演** 机制要解决的，规范集中在 **TS 33.501 Section 6.9.2（Key handling in handover）** 和 **Annex A.9/A.10/A.11**。

---

## 二、5G密钥层级全景：从K到空口的完整链路

下图标出完整层级，红色框即本文聚焦的 AS 子树（KgNB 及其派生）：

```mermaid
graph TD
    K[永久密钥 K<br/>USIM / UDM-ARPF]
    CKIK[CK, IK<br/>AKA衍生于USIM]
    KAUSF[K_AUSF<br/>AUSF - Annex A.2]
    KSEAF[K_SEAF<br/>SEAF - Annex A.6]
    KAMF[K_AMF<br/>AMF/UE - Annex A.7]
    KNAS[NAS密钥<br/>K_NASint / K_NASenc<br/>Annex A.8]
    KgNB["KgNB<br/>UE与gNB共享 - Annex A.9<br/>输入: K_AMF + 上行NAS COUNT"]
    NH["NH Next Hop<br/>Annex A.10<br/>前向安全中间密钥"]
    KRRCint[K_RRCint 完整性]
    KRRCenc[K_RRCenc 加密]
    KUPint[K_UPint UP完整性]
    KUPenc[K_UPenc UP加密]

    K --> CKIK
    CKIK --> KAUSF
    KAUSF --> KSEAF
    KSEAF --> KAMF
    KAMF --> KNAS
    KAMF -->|"垂直(初次)"| KgNB
    KgNB --> NH
    KgNB --> KRRCint
    KgNB --> KRRCenc
    KgNB --> KUPint
    KgNB --> KUPenc

    classDef focus fill:#ffe0e0,stroke:#c0392b,stroke-width:2px;
    classDef nas fill:#e8f4fd,stroke:#2980b9;
    class KgNB,NH,KRRCint,KRRCenc,KUPint,KUPenc focus;
    class KNAS nas;
```

**归属实体速记**（关键，决定谁能推演什么）：

| 密钥 | 持有实体 | 用途 |
|------|---------|------|
| K / CK / IK | USIM + UDM/ARPF | 认证根，永不下发 |
| K~AUSF~ | AUSF + UE(ME) | 认证结果锚 |
| K~SEAF~ | SEAF + UE | 服务网络绑定 |
| **K~AMF~** | **AMF + UE(ME)** | NAS锚，**推演AS密钥的总根** |
| KgNB | AMF + UE + gNB | gNB空口根密钥 |
| NH | AMF + UE（gNB只持有一个） | 切换前向安全中间量 |
| K~RRC*~/K~UP*~ | gNB + UE | 真正的空口加密/完整性密钥 |

注意一个关键设计：**gNB 永远拿不到 K~AMF~**。AMF 只把 KgNB 和"一个 NH"下发给 gNB。这正是前向安全的根基——下文详述。

---

## 三、KDF函数与推演输入参数（Annex A.1）

3GPP 所有密钥推演统一使用一个 KDF，定义在 **TS 33.220 Annex B.2**，在 33.501 Annex A.1 中引用：

```
KDF(K, S) = HMAC-SHA-256(K, S)    输出截断到所需比特长度
S = FC || P0 || L0 || P1 || L1 || ... || Pn || Ln
```

- `K`：输入密钥（父密钥）
- `FC`：1字节的函数编码（区分"推演什么密钥"）
- `Pi`：第 i 个输入参数；`Li`：Pi 的长度（2字节大端）

不同密钥只是 FC 和参数不同。下表列出 AS 密钥链相关的推演函数（Annex A 编号即规范章节）：

| 推演函数 | 父密钥 K | FC | 输入参数 P0 / P1 | 产物 | 规范定位 |
|---------|---------|-----|------------------|------|---------|
| A.7 K~AMF~ | K~SEAF~ | — | SUPI、ABBA | K~AMF~ | 注册时建立 |
| A.8 算法密钥 | KgNB 或 K~AMF~ | 0x69 | 算法类型区分符、算法标识 | K~RRCint/enc~、K~UPint/enc~、K~NASint/enc~ | SMC 时按算法派生 |
| **A.9 KgNB** | **K~AMF~** | **0x15** | **上行 NAS COUNT**（4字节） | **KgNB** | 初始/状态转移时 |
| **A.10 NH** | **K~AMF~** | **0x11** | **SYNC**（首个=KgNB，后续=上一个NH） | **NH** | 切换前向安全 |
| **A.11 KgNB\*** | **KgNB(水平)或NH(垂直)** | — | 目标 PCI、下行 ARFCN | 新 gNB 的 KgNB | 切换时 |

> **设计要点 1**：A.9 中 KgNB 绑定**上行 NAS COUNT**——这是注册后第一个 K~AMF~ 能"新鲜化"的、UE 和 AMF 双方已知且单调的量，保证每次激活安全上下文得到的 KgNB 不同，且无须额外协商。

> **设计要点 2**：A.11 中 KgNB\* 绑定**目标小区的 PCI 与下行频点 ARFCN-DL**——把密钥与"具体某个物理小区"绑死，防止跨小区密钥复用。

---

## 四、初始KgNB与首个NH的产生

AKA 完成后，UE(ME) 和 AMF 各自持有相同的 K~AMF~。随后发生以下推演（独立、无需交互，两边算出相同结果）：

```mermaid
sequenceDiagram
    participant USIM
    participant ME as UE(ME)
    participant AMF
    participant gNB as gNB(服务)

    Note over ME,AMF: AKA完成, 双方持有 K_AMF
    ME->>ME: KgNB = KDF(K_AMF, FC=0x15, 上行NAS_COUNT)<br/>(Annex A.9)
    AMF->>AMF: KgNB = KDF(K_AMF, FC=0x15, 上行NAS_COUNT)
    Note over ME,AMF: 初始 KgNB 对应 NCC=0
    ME->>ME: NH_1 = KDF(K_AMF, FC=0x11, SYNC=KgNB)<br/>(Annex A.10, 首个NH)
    AMF->>AMF: NH_1 = KDF(K_AMF, FC=0x11, SYNC=KgNB)
    Note over ME,AMF: 第一个 NH 对应 NCC=1

    AMF->>gNB: NGAP INITIAL CONTEXT SETUP REQUEST<br/>携带: KgNB + {NH_1, NCC=1} + 算法列表
    Note over gNB: gNB 持有: 当前KgNB(NCC=0) + 一个NH储备(NCC=1)
    Note over gNB: gNB 无法获得 K_AMF, 故无法自行滚动NH链
    gNB-->>ME: AS Security Mode Command (算法协商)
    Note over gNB,ME: 双方按A.8派生 K_RRCint/enc, K_UPint/enc
```

**这里有两个常被忽视的细节**：

1. **gNB 只拿到"一个" NH（NCC=1）**。AMF 不会把整条 NH 链都给 gNB。gNB 想要下一个 NH，必须等 AMF 再下发。
2. **UE 却持有 K~AMF~，因此能算出整条 NH 链**。后续 NH~n+1~ = KDF(K~AMF~, FC=0x11, SYNC=NH~n~)。这条链是单向的，gNB 没有 K~AMF~ 就滚不动——这就是前向安全的物理根源。

---

## 五、切换密钥链模型：水平 vs 垂直推演（核心机制）

切换时，源 gNB 要为目标 gNB 准备新密钥 KgNB\*。规范（33.501 6.9.2.1.1，Figure 6.9.2.1.1-1）定义了**二维密钥链**模型：

```mermaid
graph TD
    subgraph 垂直方向[垂直推演 - 用NH, 提供前向安全]
        KAMF2[K_AMF] --> NH0[NH_1 NCC=1]
        NH0 --> NH1[NH_2 NCC=2]
        NH1 --> NH2[NH_3 NCC=3]
    end
    subgraph 水平方向[水平推演 - 用当前KgNB, 仅新鲜性]
        K0[KgNB NCC=0] -->|KDF PCI+freq| K0a[KgNB* NCC=0]
        K0a -->|KDF PCI+freq| K0b[KgNB* NCC=0]
    end
    NH0 -.->|垂直派生目标密钥| K0
    NH1 -.-> K0a
```

**两条推演路径的规则**：

- **水平推演（horizontal）**：KgNB\* = KDF(**KgNB**, FC=A.11, 目标PCI, 目标ARFCN-DL)。**NCC 不变**。源 gNB 用自己当前的 KgNB 直接推。提供**密钥新鲜性**（每个小区密钥不同），但**不提供前向安全**。
- **垂直推演（vertical）**：KgNB\* = KDF(**NH**, FC=A.11, 目标PCI, 目标ARFCN-DL)。**NCC+1**。源 gNB 用储备的 NH 推。**既新鲜又前向安全**。

**为什么水平没有前向安全、垂直有？**

| 维度 | 水平推演 | 垂直推演 |
|------|---------|---------|
| 父密钥 | 当前 KgNB（gNB 自己有） | NH（gNB 只有当前一个） |
| NCC 变化 | 不变 | +1 |
| 新鲜性 | ✅（绑定目标PCI/freq） | ✅ |
| 前向安全 | ❌ | ✅ |
| 源gNB能否推算"再下一跳"密钥 | ✅（它有KgNB就能算） | ❌（滚动NH需要K_AMF） |
| 适用场景 | 同频小区快速连续切换 | 关键切换、需前向安全 |
| 规范来源 | 33.501 6.9.2.1.1 / A.11 | 33.501 6.9.2.1.1 / A.11 |

直观理解：水平链里，密钥像 `K → K1 → K2`，知道任意一个就能往后算，所以一旦 gNB 被攻破，后续水平切换密钥全部暴露。垂直链里，密钥像 `K_AMF → NH1 → NH2`，而 gNB 没有 K_AMF，被攻破后它手上的 NH~n~ 只够推算**当前这一跳**，算不出 NH~n+1~，于是后续垂直切换密钥对它是黑箱。

---

## 六、切换信令全链时序图

### 6.1 Xn 接口切换（无核心网参与密钥生成）

```mermaid
sequenceDiagram
    participant UE
    participant Src as 源gNB
    participant Tgt as 目标gNB
    participant AMF

    Note over Src: 决策: 用水平(当前KgNB) 还是 垂直(储备NH)
    Note over Src: 示例: 选择垂直推演获得前向安全
    Src->>Src: KgNB* = KDF(NH_1, PCI_tgt, ARFCN-DL_tgt)<br/>NCC_new = 1
    Src->>Tgt: XnAP HANDOVER REQUEST<br/>携带: KgNB* + NCC=1 + 安全算法
    Note over Tgt: 存为当前KgNB(NCC=1), 但没有新的NH储备
    Tgt-->>Src: XnAP HANDOVER REQUEST ACKNOWLEDGE
    Src->>UE: RRCReconfiguration (含 reconfigurationWithSync)<br/>携带: nextHopChainingCount = NCC = 1
    Note over UE: 收到NCC=1, 与本地NCC比较
    Note over UE: 本地NCC=0 < 收到的1 => 垂直推演
    UE->>UE: 先把本地NH链滚到NCC=1<br/>(UE有K_AMF, 可算NH_1)<br/>再 KgNB* = KDF(NH_1, PCI_tgt, ARFCN)
    UE-->>Tgt: RRCReconfigurationComplete (用新密钥)
    Tgt->>AMF: NGAP PATH SWITCH REQUEST
    AMF-->>Tgt: PATH SWITCH REQUEST RESPONSE
    Note over AMF,Tgt: AMF下发新的 NH + NCC=2<br/>(UE CONTEXT MODIFICATION)<br/>补充目标gNB的前向安全储备
```

**UE 侧判别水平/垂直的关键**：UE 在 `RRCReconfiguration` 里收到 `nextHopChainingCount`（即 NCC）：

- **收到的 NCC == 本地当前 NCC** → 水平推演，用当前 KgNB 派生 KgNB\*；
- **收到的 NCC > 本地当前 NCC** → 垂直推演，先把本地 NH 链滚到该 NCC，再用 NH 派生。

这就是为什么 UE 必须本地维护整条 NH 链——它要随时能对齐网络指定的任意 NCC。

### 6.2 N2 接口切换（核心网参与）

N2 切换时密钥由 AMF 直接算好下发：

```mermaid
sequenceDiagram
    participant UE
    participant Src as 源gNB
    participant AMF
    participant Tgt as 目标gNB

    Src->>AMF: NGAP HANDOVER REQUIRED (含目标信息)
    Note over AMF: AMF 用 K_AMF 推演出新 NH<br/>KgNB* = KDF(NH_n, PCI_tgt, ARFCN-DL)
    AMF->>Tgt: NGAP HANDOVER REQUEST<br/>携带: KgNB* + NCC=n + 算法
    Tgt-->>AMF: HANDOVER REQUEST ACK
    Src->>UE: HO Command (含 NCC)
    UE->>UE: 本地推演对齐NCC, 得到KgNB*
    UE-->>Tgt: 接入目标
```

> 与 Xn 切换的区别：Xn 切换密钥由源 gNB 用储备 NH 算（消耗储备）；N2 切换密钥由 AMF 用 K~AMF~ 直接算（不消耗 gNB 储备）。所以**N2 切换天然有前向安全**，而 Xn 切换的前向安全取决于源 gNB 是否还有未消耗的 NH 储备。

---

## 七、NCC推进与密钥链状态转换

下图刻画 NCC 与 NH 储备的状态机：

```mermaid
stateDiagram-v2
    [*] --> 初始: 注册完成, gNB持 KgNB(NCC=0) + NH储备(NCC=1)
    初始 --> 水平HO1: 同频快速切换(水平)
    note right of 水平HO1
        NCC保持不变(=0)
        NH储备(NCC=1)未消耗, 仍可用
        无前向安全
    end note
    水平HO1 --> 水平HO2: 再次水平
    初始 --> 垂直HO1: 关键切换(垂直)
    note right of 垂直HO1
        NCC +1 => 1
        消耗NH储备
        前向安全成立
        但目标gNB现在无NH储备!
    end note
    垂直HO1 --> 等待补充NH: 需AMF经PathSwitch/ContextMod下发新NH(NCC=2)
    等待补充NH --> 垂直HO2: 收到新NH后可再做垂直切换
```

**实战含义**：如果一个 UE 长时间停留在某个 gNB 上做了多次 Xn 水平切换，该 gNB 的 NH 储备（最初 NCC=1 那个）一直留着没用。一旦发生一次垂直切换，储备被耗尽，必须等 AMF 补充才能再有前向安全。AMF 补充的时机是 **Path Switch Request Response** 之后的 **UE Context Modification** 流程。

---

## 八、抓包识别与常见故障

### 8.1 如何在 Wireshark 里识别这套机制

- **NGAP `InitialContextSetupRequest` / `UEContextModificationRequest`**：其中的 `Security Key` 字段即下发给 gNB 的 KgNB；`Next Hop Chaining Count` 字段即 NCC，伴随 `NH`（在加密接口上不可见明文 NH，但 NCC 可见）。
- **XnAP `HandoverRequest`**：携带目标 gNB 的 `KgNB*`（`Security Key`）与 `NextHopChainingCount`。
- **RRC `RRCReconfiguration` → `reconfigurationWithSync`**：含 `nextHopChainingCount`，这是 UE 判别水平/垂直的唯一依据。
- **NAS `SecurityModeCommand`**：携带选定的 NAS 算法（NEA/NIA），驱动 A.8 派生 K~NAS*~。

可借助 `pcap-analyzer` 这类工具直接对 NGAP/XnAP/RRC 报文做字段级解析，定位 NCC 是否对齐。

### 8.2 常见故障点

| 现象 | 可能根因（密钥相关） | 排错思路 |
|------|---------------------|---------|
| 切换后业务不通/掉话 | UE 与 gNB 的 NCC 不一致，导致派生 KgNB\* 不同，完整性校验失败 | 检查 HO Command 中 NCC 与 UE 本地 NCC；查 AMF 是否正确滚动 NH |
| 切换后下行可解、上行乱码 | 算法列表协商不一致（NEA/NIA 选择不同） | 对比 SMC 中双边算法，确认 AS 算法优先级一致 |
| 频繁 Xn 切换后出现安全降级 | 多次水平推演，NH 储备耗尽未补充，后续切换无前向安全 | 检查 Path Switch 后 AMF 是否触发 Context Modification 补 NH |
| 注册后立即不通 | KgNB 推演输入的**上行 NAS COUNT** 双方不一致 | 确认注册流程 SMC 的 NAS COUNT 是否对齐 |
| DC 场景 SN 不可用 | KSN（A.16）派生或下发异常 | 检查 MN→SN 的 SgNB Addition 中密钥传递 |
## 九、近年演进：双连接、LTM 与 Key-change-on-the-fly

这套机制在 R17/R18 持续扩展：

- **Dual Connectivity（A.16 KSN）**：MR-DC 场景下，主节点（MN）持有 KgNB，为辅节点（SN）派生 **KSN** 并下发，SN 用 KSN 派生自己的空口密钥，密钥树扩展到第二节点。
- **L1/L2 Triggered Mobility（LTM，6.17，Rel-18 新增）**：LTM 追求毫秒级小区切换，密钥处理需跟上 L1/L2 的快速重选节奏；规范为 LTM 定义了专用的安全更新流程（如动态垂直密钥派生），保证快速移动下仍能保持前向安全。
- **Key-change-on-the-fly（6.9.4）**：在不中断业务、不切换的情况下，gNB 可触发 KgNB 在线刷新（基于水平推演 + PCI/freq），用于长期连接的密钥轮换。
- **学术关注点**：Linköping 大学 SECRYPT 2023 论文《5G Handover: When Forward Security Breaks》及 ETH Zürich WISEC 2021 的形式化分析指出，在特定 Xn 切换序列与 NH 储备耗尽的边缘场景下，前向安全可能被削弱，提示工程实现需谨慎管理 NH 储备补充时序。

---

## 十、常见问题

**Q1: KgNB 和 K~AMF~ 到底谁推演出谁，方向是什么？**
A: K~AMF~ 是父，KgNB 是子。KgNB = KDF(K~AMF~, FC=0x15, 上行NAS COUNT)。AMF 和 UE 各自独立用相同的 K~AMF~ 和 NAS COUNT 推演出相同的 KgNB，然后 AMF 把 KgNB 下发给 gNB。gNB 反推不出 K~AMF~（KDF 单向）。

**Q2: 水平推演和垂直推演的本质区别是什么？为什么一个有前向安全、一个没有？**
A: 水平用 KgNB（gNB 自己持有）派生下一跳，知道当前就能算未来；垂直用 NH（K~AMF~ 单向链上的一个值）派生，gNB 只握有当前一个 NH，要算下一个 NH 需要 K~AMF~（gNB 没有），所以被攻破的 gNB 算不出后续垂直切换的密钥，前向安全成立。

**Q3: UE 是怎么知道该用水平还是垂直推演的？**
A: 唯一依据是 `RRCReconfiguration` 中携带的 `nextHopChainingCount`（即 NCC）。UE 拿它和本地 NCC 比：相等则水平，更大则垂直（并先把本地 NH 链滚到该 NCC）。这也是 UE 必须本地维护完整 NH 链的原因。

**Q4: 为什么 gNB 只拿到一个 NH，而不直接拿到整条链？**
A: 拿到整条链等于把前向安全拱手让出。规范刻意让 gNB 只持"一跳"的 NH 储备（NCC+1 那个），用完即空，必须等 AMF 经 Path Switch / Context Modification 补充。这是用"信息不对称"换取安全的设计。

**Q5: Xn 切换和 N2 切换在密钥处理上有什么不同？**
A: Xn 切换密钥由**源 gNB** 用储备 NH 派生（消耗储备，前向安全取决于是否有 NH）；N2 切换密钥由 **AMF** 用 K~AMF~ 直接派生（不消耗 gNB 储备，天然有前向安全）。这也是为什么 N2 切换虽信令更重但安全性更强。

---

## 参考来源

1. [3GPP TS 33.501 — Security architecture and procedures for 5G system](https://www.3gpp.org/dynareport/33501.htm) — Annex A.9 (KgNB)、A.10 (NH)、A.11 (KgNB*)、Section 6.9.2 (Key handling in handover)、6.9.2.1.1 (Access stratum)
2. [TS 33.501 Section 6.9.2.1.1 — Access stratum (iTechSpec)](https://itecspec.com/3gpp/33.501/s/6.9.2.1.1) — 切换密钥链模型 Figure 6.9.2.1.1-1 原文解读
3. [TS 33.501 Section 6.2 — Key hierarchy, key derivation, and distribution scheme](https://itecspec.com/3gpp/33.501/s/6.2) — 密钥层级与分发结构
4. [NH — Next Hop key (3GPP Explorer Glossary)](https://3gpp-explorer.com/glossary/nh/) — NH 前向安全机制与 NCC 同步说明
5. [5G Handover: When Forward Security Breaks (Linköping University, SECRYPT 2023)](https://www.ida.liu.se/labs/rtslab/publications/2023/SECRYPT_2023.pdf) — Xn 切换前向安全的边缘场景形式化分析
6. [A Comprehensive Formal Analysis of 5G Handover (ETH Zürich, WISEC 2021)](https://people.inf.ethz.ch/rsasse/pub/5G-handover-WISEC21.pdf) — 水平/垂直推演的安全性形式化证明

---
> 本文由「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)
