<!-- title: SEPP跨域N32安全拆解 -->
<!-- domain: security -->

# SEPP跨域N32安全机制拆解：从PRINS握手到N32-f字段级加密全链解析

## 一、为什么5GC漫游必须引入SEPP——一条半可信链路的安全困局

在4G EPS时代，运营商间漫游（Home-Routed与LBO）的信令通过Diameter/GTP-C穿越IPX（IP Exchange）提供商网络。IPX是一组**半可信（semi-trusted）**的中转运营商：它必须读取部分信令字段以完成路由、结算、 lawful intercept，但又不应获知用户的敏感隐私（SUPI、鉴权向量、位置、订阅数据）。在Diameter时代，运营商只能依赖IPsec或TLS做"管道级"保护，一旦IPX做了TLS终结或镜像，整条信令便暴露无遗——这被SA3在Rel-15列为5GC的核心安全风险之一。

5GC全面SBI（Service-Based Interface，基于HTTP/2+JSON）后问题更尖锐：任意一条漫游信令（如V-AMF向H-UDM取用户数据、向H-AUSF取鉴权向量）都是结构化JSON，里面有大量需要保护的IE。3GPP给出的答案是 **SEPP（Security Edge Protection Proxy，安全边缘保护代理）**——它把每个PLMN的5GC控制面"包"起来，在两个PLMN的SEPP之间用一套全新的应用层安全协议 **PRINS（Protocol for N32 Interconnect Security，N32互联安全协议）**，对SBI消息做**字段级的选择性加密+完整性+防重放**，让IPX只看得见路由必需的明文，看不见任何敏感载荷。

> 本文聚焦 **3GPP TS 33.501 第13.2章「Application layer security on the N32 interface」** 与 **TS 29.573 第5.2.2节「Security Capability Negotiation Procedure」** 所定义的PRINS全链机制，拆解N32-c握手、密钥派生、N32-f重格式化与字段级保护，并给出抓包识别与排错实战。

## 二、SEPP在5GC中的位置与N32的双面结构

```mermaid
flowchart TD
    subgraph V["VPLMN（拜访地）"]
        UE["UE"] --> NR["gNB"]
        NR --> VAMF["V-AMF"]
        VAMF --> VNRF["V-NRF"]
        VAMF --> VSEPP["V-SEPP（cSEPP+fSEPP）"]
        VNRF --> VSEPP
    end
    subgraph H["HPLMN（归属地）"]
        HSEPP["H-SEPP（cSEPP+fSEPP）"] --> HNRF["H-NRF"]
        HSEPP --> HNF["H-UDM / H-AUSF / H-PCF"]
    end
    VSEPP =="N32-c（TLS+握手）& N32-f（PRINS）经IPX"==> HSEPP
    IPX["IPX Provider（半可信中转）"] -.路由/结算.-> VSEPP
    IPX -.路由/结算.-> HSEPP
```

SEPP在逻辑上承担两个角色，对应两条接口：

- **cSEPP（control SEPP）↔ N32-c**：控制面，负责安全能力协商、密钥协商、参数交换、错误处理，承载在**端到端TLS**之上（TS 33.501 §13.2.2，TS 29.573 §5.2.2 明确："An end to end TLS connection shall be setup between the two SEPPs"）。
- **fSEPP（forwarding SEPP）↔ N32-f**：转发面，承载经PRINS保护（JWE加密+JWS完整性+计数器防重放）后的SBI业务消息。

一条N32连接因此被"劈成两半"：N32-c建立并维护**N32-f安全上下文**，N32-f则反复使用该上下文保护海量漫游信令。这种"握手/数据"分离的设计，与TLS自身的握手/记录分离同构，使N32-f可长期复用密钥、降低每消息开销。

## 三、PRINS总体设计：TLS+应用层的双层纵深防御

一个常见疑问是：既然N32-c已建立端到端TLS，为何还要PRINS再叠一层应用层加密？答案是三个刚性需求：

1. **字段级选择性保护**：IPX必须读取路由字段（目标NF的apiRoot/FQDN、PLMN ID、NF类型、3gpp-Sbi-*相关Correlation ID），但绝不能读取SUPI/鉴权向量/位置。TLS是"全有或全无"的管道加密，无法把一条JSON"拆开"——只有应用层JWE能做到。
2. **抗IPX终结**：TLS在SEPP间端到端，但PRINS的密钥由**应用层ECDH独立派生**，与TLS会话密钥解耦；即便某IPX在传输层做手脚，应用层密文仍然不可还原。
3. **可证明的归属**：PRINS的`signature`把整条消息（含明文路由字段）绑定到对端SEPP的密钥上，IPX无法篡改路由字段重定向流量。

## 四、N32-c安全能力协商与密钥派生流程（TS 33.501 §13.2.2.2 / TS 29.573 §5.2.2）

### 4.1 完整握手时序

```mermaid
sequenceDiagram
    autonumber
    participant cI as 发起侧 cSEPP（V-SEPP）
    participant cR as 响应侧 cSEPP（H-SEPP）
    Note over cI,cR: 阶段0：先建立端到端TLS（双向证书认证）
    cI->>cR: TLS握手（证书认证，验证对端SEPP身份与PLMN）
    cR-->>cI: TLS建立完成（N32-c承载通道）
    Note over cI,cR: 阶段1：安全能力协商（Security Capability Negotiation）
    cI->>cR: POST /n32c-handshake：发起方能力集<br/>（PLMN ID、PRINS版本、支持的enc/integ算法、<br/>是否支持replay、ephemeral公钥PK_I、随机数Nonce_I）
    cR->>cI: POST /n32c-handshake（响应）：响应方能力集<br/>（选定enc/integ算法、ephemeral公钥PK_R、Nonce_R）
    Note over cI,cR: 阶段2：各自计算共享密钥并派生N32-f密钥
    cI->>cI: ECDH: Z=PK_R × sk_I<br/>KDF(HKDF-SHA256, Z) → 派生4把N32-f密钥
    cR->>cR: ECDH: Z=PK_I × sk_R（同一Z）
    Note over cI,cR: 阶段3：生成N32-f Context（含Context ID、对端信息、密钥、计数器初值）
    cI->>cR: N32-c确认（携带N32-f Context ID）
    cR-->>cI: 确认，双方各自建立Initiator/Responder安全上下文
```

### 4.2 N32-c握手关键IE说明

| IE / 参数 | 含义 | 作用 |
|-----------|------|------|
| PLMN ID (发起/响应) | 标识两端PLMN | 路由归属、证书域校验 |
| PRINS版本 | 协议版本号 | 兼容性协商 |
| 支持的加密算法集 | 如 A256GCM | 选定JWE的`enc`算法 |
| 支持的完整性算法集 | 如 HS256 | 选定JWS/签名算法 |
| ephemeral公钥 (PK_I / PK_R) | 临时ECDH公钥 | 派生N32-f共享密钥Z |
| Nonce | 双方随机数 | KDF输入，防预计算/新鲜性 |
| N32-f Context ID | 上下文标识 | 后续N32-f消息引用本上下文 |
| Replay支持指示 | 是否启用计数器防重放 | 影响计数器机制 |

### 4.3 设计意图

把密钥派生放在**应用层独立的ECDH**而非直接复用TLS的`exporter`，是为了让PRINS成为"与传输解耦"的安全层——N32-c的TLS提供**身份认证信道**，PRINS的ECDH提供**业务密钥**。两者解耦意味着更换TLS实现、增加IPX跳数都不影响PRINS的密码学绑定。这也是TS 33.501把它称作"Application layer security on top of transport security"的根因。

## 五、N32-f密钥与安全上下文（TS 33.501 §13.2.2.4）

一次成功的N32-c握手产出**一个N32-f Context**，其内含两组方向相反的密钥，对应两个Security Context：

```mermaid
flowchart TB
    KDF["HKDF-SHA256(Z, 双方Nonce)"] --> ISC["Initiator Security Context（ISC）<br/>用于保护「请求」方向 I→R"]
    KDF --> RSC["Responder Security Context（RSC）<br/>用于保护「响应」方向 R→I"]
    ISC --> KEi["K_enc_I（加密密钥, A256GCM）"]
    ISC --> KIi["K_int_I（完整性密钥, HS256）"]
    ISC --> CTi["计数器 Counter_I（防重放）"]
    RSC --> KEr["K_enc_R（加密密钥, A256GCM）"]
    RSC --> KIr["K_int_R（完整性密钥, HS256）"]
    RSC --> CTr["计数器 Counter_R（防重放）"]
```

- **ISC（Initiator Security Context）**：发起SEPP加密/签名"请求"消息时使用`K_enc_I`/`K_int_I`，响应SEPP用同一组密钥验签解密。
- **RSC（Responder Security Context）**：响应SEPP保护"响应"消息时使用`K_enc_R`/`K_int_R`。
- **共4把对称密钥 + 2个计数器**。AES-256-GCM做机密性（JWE `enc=A256GCM`），HMAC-SHA-256做完整性（JWS `alg=HS256`）。
- **计数器防重放**：每发一消息计数器+1，接收方维护滑动窗口（sliding window）检查单调性，丢弃重复或回退的N32-f消息。这抵御IPX重放历史信令发起的重放攻击（如重放一条鉴权向量请求）。

## 六、N32-f消息重格式化与字段级保护——PRINS的灵魂

这是PRINS区别于一切"管道加密"的核心机制。当V-SEPP要把一条SBI请求（如`Nudm_UEAuthentication_Get`，载荷含SUPI、SNN）发往HPLMN时，它不是整包加密，而是按 **TS 33.501数据类型敏感度分类表** 把JSON"拆解重排"。

### 6.1 重格式化流程图

```mermaid
flowchart TD
    IN["原始SBI消息<br/>{SUPI, SNN, auth向量, PLMN, NF-FQDN, Corr-ID}"] --> CLS{"按敏感度分类<br/>TS 33.501字段表"}
    CLS -->|敏感: SUPI/AUTN/RES/Kseaf/GPSI/位置| SENS["标记为ciphered，分配reference"]
    CLS -->|路由必需: PLMN-ID/NF-FQDN/apiRoot/Corr-ID| CLR["保留明文，原位不动"]
    SENS --> JWE["JWE(A256GCM)加密<br/>cipheredPart = JWE({ref1:SUPI, ref2:AUTN,...})<br/>原位置替换为 {reference: ref1}"]
    JWE --> MERGE["组装N32-f消息：<br/>metadata + 改写后body(含reference) + cipheredPart + clearTextPart"]
    CLR --> MERGE
    MERGE --> SIG["signature = HS256(K_int_I)<br/>对metadata+cipheredPart+clearTextPart+改写body整体完整性保护"]
    SIG --> OUT["POST /n32f-message 到对端fSEPP"]
```

### 6.2 N32-f消息结构（IE拆解）

经重格式化后，发往对端fSEPP的N32-f消息是一个全新的JSON，其顶层成员为：

| 顶层成员 | 内容 | 是否明文 |
|----------|------|----------|
| `metadata` | 原始请求行与重建所需头（ORIGINAL_URL、HTTP_METHOD、ORIGINAL_CONTENT_TYPE） | 明文（IPX可见，供对端SEPP重建原消息） |
| `cipheredPart` | JWE紧凑序列化串，内含`{reference→敏感值}`映射 | **密文**（仅两端SEPP可解） |
| `clearTextPart` | 引用值数组`[{reference, data}]`，用于需明文但被抽取引用的标量/数组字段 | 明文但完整性受保护 |
| `signature` | 基于完整性密钥的MAC/签名，覆盖以上全部 | 明文（验证用） |

**reference机制**是关键：每处被加密的敏感字段，其原位置被替换为一个`{reference: "refN"}`占位对象，真实值收入`cipheredPart`的JWE中。对端H-SEPP验签后，用`K_enc`解开JWE，按reference把真值"填回"原位，重建出与发起侧V-AMF完全一致的原始SBI消息，再转发给H-UDM/AUSF。对IPX而言，它只能看到`metadata`、占位的`reference`和密文`cipheredPart`——**路由所需全在，敏感内容全无**。

### 6.3 字段敏感度分类（典型）

| 类别 | 典型IE | 处理 |
|------|--------|------|
| 强敏感（必加密） | SUPI、GPSI、RAND、AUTN、HXRES*、RES*、Kseaf、鉴权向量、PEI | cipheredPart（JWE） |
| 中敏感 | TAI、NCGI、用户位置、订阅QoS、切片S-NSSAI | 通常ciphered，运营商策略可调 |
| 路由必需（明文） | PLMN ID、目标NF的apiRoot/FQDN、NF类型、3gpp-Sbi-Correlation-ID、消息类型 | 原位明文 |

> 注意：哪些字段进入`cipheredPart`由 **TS 33.501的字段分类表** 与运营商双边策略共同决定。两SEPP必须在N32-c阶段对分类策略达成一致，否则会出现"一端加密、另一端不解"的协商失败。

## 七、端到端实战：漫游用户注册触发N32-f保护的全链

下面以VPLMN漫游用户执行主认证为例，串起整条链路（V-AMF→V-SEPP→IPX→H-SEPP→H-AUSF/UDM，再原路返回）：

```mermaid
sequenceDiagram
    autonumber
    participant UE
    participant VAMF as V-AMF
    participant VSEPP as V-SEPP(fSEPP)
    participant IPX as IPX（半可信）
    participant HSEPP as H-SEPP(fSEPP)
    participant HNF as H-AUSF/H-UDM
    Note over VSEPP,HSEPP: 前提：N32-c已握手，N32-f Context(ISC/RSC)就绪
    UE->>VAMF: Registration Request（SUCI）
    VAMF->>VSEPP: Nudm_UEAuthentication_Get（含SUCI/SNN）目标HPLMN
    VSEPP->>VSEPP: 1.敏感字段分类 2.JWE加密(K_enc_I)生成cipheredPart<br/>3.原位置换reference 4.HS256(K_int_I)签名
    VSEPP->>IPX: POST /n32f-message（明文metadata+reference占位+密文cipheredPart+signature）
    Note over IPX: 仅能读metadata做路由，看不见SUPI/鉴权向量
    IPX->>HSEPP: 转发N32-f消息
    HSEPP->>HSEPP: 1.验signature(K_int_I) 2.查计数器防重放<br/>3.JWE解密(K_enc_I) 4.按reference回填重建原消息
    HSEPP->>HNF: Nudm_UEAuthentication_Get（原始明文，含SUCI）
    HNF-->>HSEPP: 鉴权向量（RAND/AUTN/...）
    HSEPP->>HSEPP: 用RSC(K_enc_R/K_int_R)对响应做PRINS保护
    HSEPP->>IPX: N32-f响应（密文+签名）
    IPX->>VSEPP: 转发响应
    VSEPP->>VSEPP: 验签解密回填，重建原始响应
    VSEPP-->>VAMF: Nudm_UEAuthentication_Get 响应（明文鉴权向量）
    VAMF-->>UE: Authentication Request（RAND/AUTN）
```

设计要点回顾：**明文路由字段保证IPX可路由，密文敏感字段保证端到端机密性，计数器与signature保证完整性与防重放**——四者缺一不可。

## 八、与"纯TLS管道保护"方案对比

| 维度 | 传统TLS-over-IPX | PRINS（SEPP N32） |
|------|------------------|-------------------|
| 保护粒度 | 整包管道级 | **字段级选择性** |
| IPX可见性 | 全有/全无 | 仅路由字段 |
| 抗IPX终结 | 弱（依赖TLS不被终结） | 强（应用层密钥独立） |
| 防重放 | 依赖TLS序列号，跨PLMN弱 | **计数器+滑动窗口** |
| 完整性归属 | TLS层 | 应用层signature，可证明来源 |
| 跨多IPX跳 | 每跳可能需重协商 | N32-f上下文跨跳复用 |

## 九、抓包识别与故障排错实战

### 9.1 抓包如何识别N32流程

在SEPP与IPX之间的镜像口抓包（HTTP/2 over TLS）：

1. **N32-c握手**：`POST /n32c-handshake/...` 资源，TLS应用数据内可见能力协商（若TLS未解密则只见密文）。先有N32-c，后有N32-f。
2. **N32-f转发**：`POST /n32f-message/...`（dstest.info的"N32-f Message Forwarding"字典即此操作），请求体为JSON，含`metadata`、`cipheredPart`（长base64url的JWE五段式）、`clearTextPart`、`signature`。
3. **特征**：消息体里出现 `"reference"` 占位对象 + 一大段JWE紧凑串，且**看不到SUPI/鉴权向量明文**，即可判定PRINS已生效。

### 9.2 常见故障点

| 故障现象 | 根因 | 排错思路 |
|----------|------|----------|
| N32-c握手失败 | 证书不受信/PLMN域不匹配/算法集无交集 | 检查SEPP互信证书、PLMN-ID配置、算法交集 |
| N32-f验签失败 | signature不通过 | K_int派生参数（Nonce/Z）两端不一致；检查ECDH公钥交换完整性 |
| N32-f解密失败 | cipheredPart用错密钥/Context | 确认用了正确的ISC/RSC、Context ID匹配 |
| 字段协商不一致 | 一端加密某字段，对端策略未列 | 核对双边字段分类表（TS 33.501）与运营商SLA |
| 合法信令被丢弃 | 计数器回退/重复，落入滑动窗口外 | 检查时钟/计数器同步、是否经异常IPX复制流量 |
| 路由失败 | 路由字段被误加密 | 确认apiRoot/PLMN/Corr-ID留在明文 |
## 十、常见问题

**Q1: N32-c已有端到端TLS，为何还要PRINS的应用层JWE/JWS？**
A: 三点：①字段级选择性加密，让IPX只读路由字段、读不到敏感载荷（TLS做不到"拆包"）；②应用层密钥独立于TLS会话，抗IPX传输层干预；③计数器+signature提供可证明来源的完整性与跨PLMN防重放。

**Q2: Initiator Security Context与Responder Security Context为何要分开？**
A: 请求与响应方向相反，分别用独立密钥集（`K_enc/K_int`各一对）可避免双向流量的密钥重用风险，并使每方向的计数器各自单调递增、互不干扰，重放检测更精确。

**Q3: IPX能否看到SUPI？**
A: 不能。SUPI属强敏感字段，进入`cipheredPart`经JWE加密，IPX只见`reference`占位与密文。IPX仅能看到`metadata`中的路由字段（PLMN、apiRoot、Corr-ID等）。

**Q4: reference机制出错（一端加密、对端不解）会怎样？**
A: 对端SEPP验签/解密后无法按reference回填，重建失败，返回N32-c错误处理流程；根因多为双边字段分类策略不一致，须核对TS 33.501分类表与运营商双边SLA。

**Q5: Home-Routed与LBO两种漫游的N32保护有区别吗？**
A: N32保护机制本身一致（都经SEPP+PRINS）。区别在流量模型：Home-Routed的会话相关信令（如Nsmf）也要跨N32，N32-f负载更重，对计数器窗口与Context更新周期更敏感；LBO则主要集中在鉴权与订阅数据查询。

## 参考来源

1. [3GPP TS 33.501 — Security architecture and procedures for the 5G system](https://www.3gpp.org/dynareport/33501.htm) — §13.2 Application layer security on the N32 interface（§13.2.1 General、§13.2.2 N32-c connection、§13.2.2.2 Key agreement、§13.2.2.4 N32-f Context）
2. [3GPP TS 29.573 — 5G System; PLMN Interconnection; Stage 3](https://www.3gpp.org/dynareport/29573.htm) — §5.2.2 Security Capability Negotiation Procedure（N32-c握手/N32-f转发服务操作定义）
3. [3GPP — 5G Roaming Security (SA3)](https://www.3gpp.org/technologies/roaming-security-sa3) — SEPP/PRINS漫游安全架构总览
4. [P1 Security — SEPP Security in 5G Roaming: N32, Threats, Risks, and Best Practices](https://www.p1sec.com/blog/sepp-security-in-5g-roaming-how-the-security-edge-protection-proxy-protects-inter-operator-trust) — N32威胁模型与IPX半可信边界分析
5. [GSMA NG.146 — Inter-SEPP Connection Testing Guidelines](https://www.gsma.com/newsroom/gsma_resources/ng-146-inter-sepp-connection-testing-guidelines-v1-0/) — 多厂商SEPP互通测试与N32握手实战

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