<!-- title: 5G AS安全模式控制信令全链拆解 -->
<!-- domain: security -->

# 5G AS安全模式控制（AS SMC）信令全链拆解：从KgNB分发到KRRCint/KRRCenc激活

当UE完成与AMF之间的NAS层5G-AKA主认证和NAS安全模式控制（NAS SMC）之后，空口安全的故事才刚刚过半。真正把"安全"落到每一比特空口无线帧上的，是gNB与UE之间执行的一段常被低估、却决定了整个RRC连接可信根基的流程——**接入层安全模式控制（Access Stratum Security Mode Control，AS SMC）**。它由RRC层触发，以一条明文（仅完整性保护）的`SecurityModeCommand`起手，以第一条同时受完整性保护和加密的`SecurityModeComplete`收尾，在中间完成算法协商、四把AS密钥派生、SRB与DRB的PDCP安全重配置三件事。

本文以3GPP TS 38.331 Section 5.3.3（RRC层SMC过程）、TS 33.501 Section 6.2/6.4/6.6（密钥层级与派生）、TS 38.501（算法定义）和TS 38.331 §6.2.2（消息IE定义）为主线，逐信令、逐IE拆解这条流程，并给出抓包识别方法。

---

## 一、机制定位：AS安全激活在整个接入信令中的位置

AS安全激活不是孤立事件，它必须嵌在"NAS安全已就绪"和"RRC专用连接已建立"两个前置条件都满足之后才能发生。理解它在时序中的位置，是排错的第一步。

```mermaid
sequenceDiagram
    participant UE
    participant gNB
    participant AMF

    Note over UE,AMF: 阶段0：NAS安全已建立（前置条件）
    UE->>AMF: Registration Request
    AMF->>UE: Authentication Request/Response (5G-AKA)
    AMF->>UE: NAS Security Mode Command
    UE->>AMF: NAS Security Mode Complete (NAS已加密+完整性保护)

    Note over UE,gNB: 阶段1：RRC专用连接建立（明文）
    UE->>gNB: RRCSetupRequest (明文)
    gNB->>UE: RRCSetup (建立SRB1，明文)
    Note over UE,gNB: 此时仅SRB1，全部明文，无任何安全

    Note over gNB,AMF: 阶段2：AMF下发初始上下文（携带KgNB）
    AMF->>gNB: InitialContextSetupRequest<br/>(含KgNB、UE安全能力、AllowedAlgorithms)
    gNB->>AMF: InitialContextSetupResponse

    Note over UE,gNB: 阶段3：AS安全激活（本文核心）
    gNB->>UE: RRC SecurityModeCommand (完整性保护，不加密)
    UE->>gNB: RRC SecurityModeComplete (完整性保护+加密)

    Note over UE,gNB: 阶段4：SRB2/DRB建立（全部已加密+完整性保护）
    gNB->>UE: RRCReconfiguration (建立SRB2/DRB，已保护)
    UE->>gNB: RRCReconfigurationComplete (已保护)
```

**设计意图（为什么这样排）：**

1. **"先验真，再上锁"**：RRCSetupRequest/RRCSetup在安全激活之前必然是明文的——因为此时gNB还没有KgNB，无从派生AS密钥。标准明确允许这两条明文消息存在，但仅限于建立SRB1所需的最小IE，不携带任何用户敏感数据。
2. **KgNB由AMF而非UE推导**：这是5G相对4G的一个微妙但重要的不变量。`KgNB`是从`KAMF`派生的，而`KAMF`在NAS认证完成后就同时存在于UE和AMF。AMF在InitialContextSetupRequest中把KgNB"递"给gNB，gNB从此具备空口加密能力——这保证了gNB永远不接触根密钥K，密钥层级是单向、向下收紧的。
3. **SMC是第一条受保护的RRC消息**：从SecurityModeCommand起，下行RRC进入完整性保护；从SecurityModeComplete起，上下行RRC同时进入完整性保护+加密。这个分界点被Wireshark标注为"first ciphered/integrity protected message"，是抓包定位的黄金锚点。

---

## 二、AS密钥层级与四把AS子密钥的派生

AS SMC执行期间，UE和gNB各自独立地、用相同的输入推导出完全一致的**四把AS子密钥**。它们都派生自`KgNB`，但用途严格分离。

### 2.1 密钥层级树

```mermaid
graph TD
    K["永久根密钥 K<br/>(USIM + UDM/ARPF)"]
    K -->|5G-AKA/ EAP-AKA'| CKIK["CK', IK'<br/>(认证衍生产物)"]
    CKIK --> KAUSF["KAUSF<br/>(AUSF派生)"]
    KAUSF --> KAMF["KAMF<br/>(AMF派生, NAS密钥根)"]
    KAMF -.->|NAS层| K_NASenc["KNASenc (NAS加密)"]
    KAMF -.->|NAS层| K_NASint["KNASint (NAS完整性)"]
    KAMF -->|KDF, P0=downlink/uplink| KgNB["KgNB<br/>(AS密钥根, gNB持有)"]
    KgNB --> K_RRCint["KRRCint<br/>(RRC完整性)"]
    KgNB --> K_RRCenc["KRRCenc<br/>(RRC加密)"]
    KgNB --> K_UPint["KUPint<br/>(用户面完整性, R15新增可选)"]
    KgNB --> K_UPenc["KUPenc<br/>(用户面加密)"]

    style KgNB fill:#fff3cd,stroke:#856404
    style K_RRCint fill:#d4edda,stroke:#155724
    style K_RRCenc fill:#d4edda,stroke:#155724
    style K_UPint fill:#d1ecf1,stroke:#0c5460
    style K_UPenc fill:#d1ecf1,stroke:#0c5460
```

### 2.2 KDF派生的输入参数（TS 33.501 Annex A.9）

所有AS子密钥都使用统一的HMAC-SHA-256密钥派生函数`KDF(KgNB, S)`，其中串`S`的差别只在于一个区分用途的标签串`P0`和一个长度字节`L0`。下表给出四把密钥派生时的关键差异：

| 派生密钥 | KDF输入P0（算法类型标签） | 用途 | 终结点 | 绑定的算法 |
|---------|----------------------|------|--------|-----------|
| `KgNB` | 来自KAMF，参数含uplink/downlink NAS COUNT | AS根密钥 | gNB | — |
| `KRRCint` | "RRC-integrity" | SRB1/SRB2完整性保护 | gNB-PDCP | NIA0/1/2/3 |
| `KRRCenc` | "RRC-encryption" | SRB1/SRB2加密 | gNB-PDCP | NEA0/1/2/3 |
| `KUPint` | "UP-integrity" | DRB完整性保护（可选） | gNB-PDCP | NIA0/1/2/3 |
| `KUPenc` | "UP-encryption" | DRB加密 | gNB-PDCP | NEA0/1/2/3 |

> **关键细节（常被忽略）：** `KgNB`派生时还会以**uplink NAS COUNT**（首次接入）作为KDF输入之一。这意味着每执行一次新的注册/主认证，KgNB都不同——这是5G实现前向安全（forward security）的基石：即使gNB当前KgNB泄露，攻击者也无法回推历史空口流量（参见TS 33.501 §6.12.2关于KgNB的前向/后向安全定义）。

### 2.3 为什么是"四把"而不是"两把"？

LTE时代AS安全只有`KRRCenc/KRRCint`和`KUPenc`三把，**用户面没有完整性保护**。这在4G时代被证明是重大隐患——伪基站可以通过篡改用户面分组实施降质攻击或注入攻击。5G在TS 33.501 §5.4.2中新增了`KUPint`，并要求：**对于QoS流5QI 6~9之外的、承载敏感业务（如控制面信令承载的UP、IMS媒体）的DRB，UP完整性保护应被启用**。这就是为什么R15之后出现了"用户面完整性保护激活"这一可单独成文的专题。

---

## 三、SecurityModeCommand：逐IE拆解

`SecurityModeCommand`（TS 38.331 §6.2.2）是SMC过程的发起消息，由gNB下行发送。它本身**只做完整性保护，不做加密**——因为此刻下行加密密钥`KRRCenc`虽已就绪，但加密必须在收发双方"约定生效点"之后才能启用，而约定的生效点正是这条消息所携带的`securityConfigSMC`。

### 3.1 消息ASN.1结构（精简版）

```
SecurityModeCommand ::=       SEQUENCE {
    rrc-TransactionIdentifier     RRC-TransactionIdentifier,
    criticalExtensions            CHOICE {
        securityModeCommand       SecurityModeCommand-IEs
    }
}

SecurityModeCommand-IEs ::=    SEQUENCE {
    securityConfigSMC            SecurityConfigSMC,
    lateNonCriticalExtension     OCTET STRING        OPTIONAL,
    nonCriticalExtension         SEQUENCE {}         OPTIONAL
}

SecurityConfigSMC ::=         SEQUENCE {
    securityAlgorithmConfig      SecurityAlgorithmConfig
}

SecurityAlgorithmConfig ::=   SEQUENCE {
    integrityProtectionAlgorithm    IntegrityProtAlgorithm   OPTIONAL,  -- 选定的NIA
    cipheringAlgorithm              CipheringAlgorithm       OPTIONAL   -- 选定的NEA
}
```

### 3.2 关键IE说明表

| IE名称 | 取值/类型 | 含义与作用 |
|--------|----------|-----------|
| `rrc-TransactionIdentifier` | 0~3 | RRC事务标识，UE用它把后续的Complete/Failure与本Command配对 |
| `securityAlgorithmConfig.integrityProtectionAlgorithm` | nia0/nia1/nia2/nia3 | **gNB为RRC选定**的完整性算法，立即用于本消息的下行完整性校验 |
| `securityAlgorithmConfig.cipheringAlgorithm` | nea0/nea1/nea2/nea3 | **gNB为RRC选定**的加密算法，从下一条消息（即UE的Complete）开始生效 |
| （隐式）承载完整性MAC | — | 整条消息用`KRRCint`+所选NIA计算MAC-I，附在PDCP头之后 |

### 3.3 gNB的算法选择逻辑（TS 33.501 §6.4）

gNB如何从众多候选中挑出一对算法？这是一次典型的"三方交集取最高优先级"操作：

```mermaid
flowchart TD
    A["UE安全能力<br/>(UESupports: NEA1/2/3, NIA1/2/3)"] --> I((交集))
    B["AMF在InitialContextSetup<br/>下发的UENetworkCapability"] --> A
    C["gNB本地配置的<br/>Allowed算法优先级表"] --> I
    D["运营商策略<br/>(如禁止NEA0用于非紧急)"] --> I
    I --> P["选定优先级最高的<br/>NEA_x + NIA_y 组合"]
    P --> CMD["填入SecurityModeCommand"]
```

选择规则要点：

1. **完整性算法优先于加密算法**：完整性保护是强制的（除非null），加密理论上可被运营商策略关闭（仅紧急呼叫允许null）。因此gNB**必须**选定一个非null的NIA（对正常注册的UE）。
2. **优先级由高到低**：典型运营商配置为 `nea2(AES-128) > nea1(Snow3G based) > nea3(ZUC)`，NIA同理。取UE支持列表与gNB允许列表交集中优先级最高者。
3. **NEA0/NIA0仅限紧急**：null算法（NEA0/NIA0）只在"未经认证的紧急呼叫"场景允许，gNB会根据AMF下发的`ueSecurityCapability`中是否标记emergency做判断。

---

## 四、UE侧处理与SecurityModeComplete

收到SecurityModeCommand后，UE执行一系列严格有序的本地操作，然后回送Complete或Failure。这是整个过程中"出错概率最高"的环节。

### 4.1 UE处理时序图

```text
sequenceDiagram
    autonumber
    participant UE_L1 as UE-PDCP/RRC
    participant UE_USIM as UE(密钥栈)

    UE_L1->>UE_L1: 收到SecurityModeCommand (PDCP下行, 含MAC-I)
    UE_L1->>UE_USIM: 1. 用当前KRRCint + 所选NIA 校验完整性MAC
    alt 完整性校验失败
        UE_L1->>UE_L1: 丢弃消息，进入RRC_IDLE (安全失败)
    else 校验通过
        UE_USIM->>UE_USIM: 2. 校验UE是否支持所选NEA/NIA
        alt 不支持
            UE_L1->>UE_L1: 构造 SecurityModeFailure (明文, 不完整性保护)
            Note right of UE_L1: Failure消息本身仍受完整性保护? <br/>否——Failure用旧配置(无保护)发送
        else 支持
            UE_USIM->>UE_USIM: 3. 派生新的KRRCint/KRRCenc/KUPenc/KUPint (KDF)
            UE_USIM->>UE_L1: 4. 配置PDCP: 下行应用新NIA+新KRRCint (生效)
            UE_L1->>UE_L1: 5. 配置PDCP: 上/下行加密用新NEA+新KRRCenc
            UE_L1->>UE_L1: 6. 为已有DRB(若已存在)做PDCP重建/安全重配
            UE_L1->>UE_L1: 7. 构造SecurityModeComplete
            UE_L1->>UE_L1: 8. Complete用新KRRCint+新KRRCenc加密+完整性保护发送
            UE_L1->>>UE_L1: 完成，AS安全激活成功
        end
    end
```

### 4.2 关键设计点：Complete是"第一条加密消息"

TS 38.331 §5.3.3.4明确规定：

> The UE shall submit the `SecurityModeComplete` message to lower layers with the indication that **integrity protection and ciphering shall be applied**, while the `SecurityModeCommand` was sent with integrity protection only.

这制造了一个巧妙的"原子生效点"：
- **下行加密生效点** = gNB发送SMC之后、发送下一条RRC消息（通常是RRCReconfiguration）时；
- **上行加密生效点** = UE发送Complete之时；
- **双向完整性生效点** = gNB发送SMC之时（下行）、UE发送Complete之时（上行，Complete首条完整性保护上行）。

由于Complete必须用刚刚派生的新密钥加密，gNB收到Complete后若能用新KRRCenc成功解密，就**隐式证明**了：双方派生的KRRCenc一致、算法选择成功、密钥派生输入（uplink NAS COUNT等）一致。这是一种无需额外握手的"密钥确认"机制。

### 4.3 SecurityModeComplete消息结构

```
SecurityModeComplete ::=     SEQUENCE {
    rrc-TransactionIdentifier     RRC-TransactionIdentifier,  -- 与Command配对
    criticalExtensions            CHOICE {
        securityModeComplete      SecurityModeComplete-IEs
    }
}
SecurityModeComplete-IEs ::=  SEQUENCE {
    lateNonCriticalExtension     OCTET STRING        OPTIONAL,
    nonCriticalExtension         SEQUENCE {}         OPTIONAL
}
```

注意：Complete消息体**几乎为空**，不携带任何业务IE。它的存在本身就是信号——"我已激活安全"。这也是为什么它必须加密：明文Complete没有信息量，加密它的意义在于验证密钥协商的正确性。

---

## 五、SecurityModeFailure：失败路径与状态机

当UE不支持所选算法或完整性校验失败时，走Failure路径。

```mermaid
stateDiagram-v2
    [*] --> RRC_IDLE
    RRC_IDLE --> RRC_CONNECTING: RRCSetupRequest
    RRC_CONNECTING --> SRB1_Established: RRCSetup
    SRB1_Established --> AS_Security_Activating: 收到SecurityModeCommand
    AS_Security_Activating --> AS_Secured: SecurityModeComplete
    AS_Security_Activating --> AS_Security_Failed: SecurityModeFailure/完整性校验失败
    AS_Security_Failed --> RRC_IDLE: gNB释放连接(RRCRelease)
    AS_Secured --> SRB2_DRB_Configuring: RRCReconfiguration
```

**Failure消息的特殊性（TS 38.331 §5.3.3.5）：**

> The UE shall submit the `SecurityModeFailure` message to lower layers **without integrity protection and without ciphering**.

为什么Failure反而是明文？因为Failure意味着新安全上下文建立失败，UE此时不能"用还不确认正确的密钥"去保护任何消息；同时旧的安全状态（即"无AS安全"）也必须能正常表达。gNB收到Failure后，通常发送`RRCRelease`让UE回IDLE，或重试时选用UE支持的其他算法组合。

---

## 六、抓包识别与故障定位实战

### 6.1 在Wireshark中识别AS SMC流程

| 抓包过滤/特征 | 判读要点 |
|--------------|---------|
| 协议栈顺序 | RRC Setup → **SecurityModeCommand** → **SecurityModeComplete** → RRC Reconfiguration |
| SecurityModeCommand的PDCP层 | `Integrity Check: OK`，`Ciphered: No`（明文） |
| SecurityModeComplete的PDCP层 | `Ciphered: Yes`，`Integrity Check: OK`——出现MAC-I正确 |
| Wireshark备注 | "This is the first integrity protected/ciphered message" 字样 |
| 关键IE | 展开NR RRC → `securityAlgorithmConfig` → 可看到`nia2`/`nea2`等枚举值 |

**TShark命令行示例**（需配合KRRCenc密钥注入才能解密Complete）：

```bash
# 提取所有SecurityMode相关RRC消息
tshark -r capture.pcapng -Y 'nr-rrc.securityModeCommand || nr-rrc.securityModeComplete || nr-rrc.securityModeFailure' -V

# 查看PDCP安全状态
tshark -r capture.pcapng -Y 'pdcp.nr' -T fields \
  -e frame.number -e nr-rrc.msg_type \
  -e pdcp.nr.ciphered -e pdcp.nr.integrity_checked
```

> 解密需要把`KRRCenc`/`KRRCint`注入Wireshark的`nr-rrc`解码器（偏好设置→Protocols→NR RRC→Security），密钥通常需要从gNB/USIM调试接口导出，或用已知根密钥K离线KDF推算。

### 6.2 常见故障点与排错树

| 故障现象 | 根因 | 排错方向 |
|---------|------|---------|
| 收到SMC后直接SecurityModeFailure | UE不支持gNB选定的算法（如UE仅支持NEA2，gNB却选NEA3） | 核对`securityAlgorithmConfig`值与`UESecurityCapability`，检查gNB算法优先级配置 |
| SMC完整性校验失败 | KRRCint派生输入不一致（如uplink NAS COUNT取值不同） | 比对UE与AMF/gNB侧NAS COUNT初值，确认是否复用了旧的KgNB |
| 无Complete也无Failure，UE超时回IDLE | PDCP配置错误、密钥未下到PDCP层 | 检查gNB侧PDCP entity建立，确认SecurityConfigSMC已下发到MAC/RLC/PDCP |
| Complete被gNB解密失败 | UE/gNB派生KRRCenc时算法串/长度不一致 | 抓KDF输入串，比对"RRC-encryption"标签及L0字节序 |
| 注册能成功但DRB无UP完整性 | 运营商未强制UP完整性，仅RRC有保护 | 核对InitialContextSetup中的`ueSecurityCapability`和gNB对DRB的`pdcp-Config`完整性开关 |
## 七、AS SMC与NAS SMC的对比

| 维度 | NAS SMC（AMF↔UE） | AS SMC（gNB↔UE） |
|------|------------------|------------------|
| 规范 | TS 24.501 §4.4.4 / TS 33.501 | TS 38.331 §5.3.3 / TS 33.501 |
| 发起方 | AMF | gNB |
| 密钥根 | KAMF | KgNB（由KAMF派生） |
| 派生密钥 | KNASenc, KNASint | KRRCenc, KRRCint, KUPenc, KUPint |
| 消息 | NAS Security Mode Command/Complete | RRC SecurityModeCommand/Complete/Failure |
| 保护对象 | NAS信令 | RRC信令 + 用户面(NR用户面) |
| Command是否加密 | 仅完整性保护 | 仅完整性保护 |
| Complete是否加密 | 完整性+加密 | 完整性+加密 |
| 触发时机 | 主认证完成后 | InitialContextSetup下发KgNB后 |

二者结构高度对称，但AS多出两把UP密钥，且KgNB不在UE中"被下发"而是UE自行派生——这是AS与NAS最大的实现分水岭。

---

## 常见问题

**Q1: 为什么SecurityModeCommand是明文（不加密），却能完整性保护？**
A: 因为完整性保护密钥`KRRCint`和加密密钥`KRRCenc`是独立派生的。gNB在构造Command前已用KDF推出`KRRCint`，因此可以立即计算MAC-I做完整性保护。但不加密的原因是：加密需要收发双方约定"生效时刻"，而Command正是用来协商算法的——在算法生效前不能加密。完整性先行、加密后行，是这个鸡生蛋问题的标准解法。

**Q2: SecurityModeComplete消息体是空的，那它存在的意义是什么？**
A: 它是被加密+完整性保护发送的，其解密成功本身就是一个**密钥一致性确认**。gNB能用新生成的`KRRCenc`成功解开Complete，等价于隐式确认"双方派生出的AS密钥完全一致"。这是一种无需额外确认字段的握手机制。

**Q3: UE如果发现gNB选的算法不支持，为什么发的是明文Failure？**
A: 因为Failure意味着新的安全上下文建立失败，UE此时不能使用"尚未确认正确"的密钥保护任何消息；旧状态（无AS安全）又必须能正常表达，故按TS 38.331 §5.3.3.5要求明文发送。gNB据此可决定降级算法重试或释放连接。

**Q4: KgNB为什么不由UE"接收"而是自行派生？**
A: KgNB派生自KAMF，而KAMF在NAS认证完成后UE与AMF同时持有。双方用相同的KDF输入各自派生KgNB，避免在空中"传输"密钥本身——任何密钥都不应在网络中明文传递，这是端到端安全的基本原则。AMF只是把派生出的KgNB通过N2接口（InitialContextSetup）安全地递交给gNB。

**Q5: 切换场景下AS SMC会重新执行吗？**
A: 通常不重走完整的SMC过程。切换（Xn/N2切换）时gNB通过`KgNB*`的水平/垂直派生得到新gNB的密钥，直接复用算法配置，在RRCReconfiguration中携带`securityConfig`做密钥刷新即可。只有在算法需要改变或安全上下文需要完全重建时，才可能触发新的SMC。

---

## 参考来源

1. [3GPP TS 38.331 V18.x — NR RRC Protocol Specification, §5.3.3 Security mode control procedure](https://www.3gpp.org/dynareport/38331.htm) — SMC过程的RRC层定义、消息IE结构
2. [3GPP TS 33.501 — Security architecture and procedures for the 5G System, §6.2/§6.4/Annex A.9](https://www.3gpp.org/dynareport/33501.htm) — 密钥层级、AS密钥派生KDF、算法选择规则
3. [TelecomTrainer — 5G-NR AS Security Procedure Explained: From Initial Context Setup to Security Mode Complete](https://www.telecomtrainer.com/5g-nr-as-security-procedure-explained-from-initial-context-setup-to-security-mode-complete/) — AS安全流程消息流逐步解读
4. [ShareTechnote — 5G Security](https://www.sharetechnote.com/html/5G/5G_Security.html) — KgNB→KRRCint/KRRCenc/KUPenc/KUPint密钥派生与终结点
5. [3glteinfo — 5G NR Security Mode Command/Complete RRC Message](https://www.3glteinfo.com/messages/5g/rrc/5g-rrc-security-mode-command/) — SMC消息字段与Complete首条加密消息说明

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