首页 › security › 5G SBI服务化接口OAuth2令牌安全拆解

5G SBI 服务化接口安全:NRF OAuth2/JWT 令牌与 mTLS 双层防护全链拆解

子域轮转:2026 年第 177 天,本轮聚焦 security(网络安全)。本文专门拆解 5GC 服务化架构(SBA)中 NF 之间的认证与授权机制——这是一条与 UE 侧主认证完全独立、却同样决定整网安全基线的"NF 间安全链"。

一、为什么 SBI 需要一套独立的安全机制

5G 核心网(5GC)彻底转向服务化架构(Service-Based Architecture, SBA):所有网络功能(NF)不再用点对点专用接口(如 4G 的 S6a/S11),而是通过统一的 HTTP/2 RESTful 服务化接口(SBI)相互调用,并由 NRF(Network Repository Function)充当"服务注册中心 + 授权服务器"。

这套架构带来了一个 4G 没有的新安全命题:任意两个 NF 之间都可能发生服务调用,而且调用链经常跨越多个中间节点(负载均衡器、消息代理、跨 PLMN 的 SEPP)。如果只靠传输层的 TLS,会出现两个致命问题:

  1. TLS 是"逐跳(hop-by-hop)"的:当报文经过代理或 SEPP 转发时,TLS 会话在中间节点上被解密再重新加密,攻击者或被攻陷的中间节点可以篡改业务报文体。
  2. TLS 只能证明"管道"可信,不能表达"业务授权":TLS 的证书只能回答"你是谁",却无法回答"你有没有权限调用这个 NF 的这个具体服务操作、访问这个 SUPI 的数据"。

因此 3GPP 在 TS 33.501 第 13 章为 SBI 设计了双层安全架构:传输层做相互认证与机密性/完整性保护,消息层做细粒度授权与端到端完整性。理解这两层如何分工、如何衔接,是 5GC 安全研发与运维的基础。

二、双层安全架构总览

flowchart TB
    subgraph T["传输层安全(TS 33.501 §13.2)"]
        T1["mTLS 双向认证<br/>基于证书(NDS/IP)"]
        T2["逐跳机密性 + 完整性<br/>HTTP/2 over TLS 1.2/1.3"]
        T3["信任范围:单个安全域 / 单跳"]
    end
    subgraph M["消息层安全(TS 33.501 §13.3)"]
        M1["OAuth2 授权<br/>NRF 作为授权服务器"]
        M2["JWT/JWS 签名<br/>端到端完整性 + 不可否认"]
        M3["信任范围:NF-A ↔ NF-B 端到端"]
    end
    UE["NF Service Consumer<br/>(如 AMF/SMF)"] --> T --> M --> PROD["NF Service Producer<br/>(如 UDM/PCF)"]
    style T fill:#e8f0fe,stroke:#1a73e8
    style M fill:#fce8e6,stroke:#d93025

两层各司其职,核心分工如下:

维度 传输层(Transport) 消息层(Message)
标准出处 TS 33.501 §13.2 TS 33.501 §13.3 / TS 29.510 §5.4
主要机制 mTLS(双向证书)+ NDS/IP OAuth2 令牌 + JWT/JWS 签名
解决的问题 "双方是谁" + 管道加密 "能否调用此服务" + 端到端完整性
保护粒度 整个 TCP/HTTP 连接 单条 SBI 请求/响应报文体
保护范围 逐跳(hop-by-hop) 端到端(NF 源到 NF 宿)
中间节点影响 被代理即被解密 签名贯穿全程,中间节点无法伪造

设计意图非常清晰:TLS 保证"路"是安全的,OAuth2/JWT 保证"信"是可信的。即使报文穿过 SEPP、负载均衡器等中间设施,只要 JWT 签名验证通过,目的 NF 就能确信报文确实来自声称的源 NF 且未被篡改。

三、传输层:mTLS 与 NDS/IP

SBI 默认承载在 HTTP/2 over TLS 之上。在同一个安全域(Security Domain)内,NF 与 NRF、NF 与 NF 之间通过相互 TLS 认证(mTLS)建立加密通道:双方都要出示并由对方校验 X.509 证书。

这一层的信任根来自 NDS/IP(Network Domain Security for IP,TS 33.310):每个安全域部署一个或多个证书签发体系(通常为运营商私有的 CA),跨安全域时则在边界节点(如 SEPP)之间通过 IPsec 或专用的网络域安全策略打通。值得注意的是,NRF 自己也支持在 NfProfile 中携带 nfServiceList、plmnList、sNssais 等属性,便于在发现阶段就做域内/域间过滤,但身份认证本身仍然由 mTLS 完成,而不是靠这些元数据。

mTLS 解决了"管道加密"问题,但它管不到"这条 HTTP 报文里授权了哪个服务"。这就引出了核心的消息层机制——OAuth2。

四、消息层核心:NRF 作为 OAuth2 授权服务器

4.1 模型:OAuth2 在 SBI 中的角色映射

TS 33.501 §13.3.1 明确规定:NF 与 NRF 之间的认证与授权应使用 OAuth2。3GPP 把标准 OAuth2(RFC 6749)的角色做了如下映射:

消费者要调用生产者的某个服务前,先向 NRF 申请一个 OAuth2 Access Token,再带着这个令牌向生产者发起服务请求;生产者验证令牌后才提供服务。NRF 因此成为全网统一的信任代理与授权中心。

4.2 完整信令时序图

下图以"AMF 调用 UDM 的 Nudm_SDM 服务(获取签约数据)"为例,展示完整的 OAuth2 令牌获取与服务调用链:

sequenceDiagram
    autonumber
    participant C as AMF<br/>(NF Consumer)
    participant N as NRF<br/>(授权服务器)
    participant P as UDM<br/>(NF Producer)

    Note over C,N: 步骤①发现(可选:已缓存则跳过)
    C->>N: GET /nnrf-disc/v1/nf-instances<br/>(target-nf-type=UDM, requester-nf-type=AMF)
    N-->>C: 200 OK (UDM 实例信息 + 服务列表)

    Note over C,N: 步骤② mTLS + OAuth2 令牌请求
    C->>N: POST /oauth2/token<br/>grant_type=client_credentials<br/>nfInstanceId={AMF id}<br/>nfType=AMF, targetNfType=UDM<br/>targetNfInstanceId={UDM id}<br/>scope="nudm-sdm"
    N->>N: 校验 mTLS 证书 + 校验 scope 授权
    N-->>C: 200 OK<br/>access_token = JWS(AccessTokenClaims)<br/>expires_in=3600

    Note over C,P: 步骤③ 带 Bearer 令牌调用服务
    C->>P: GET /nudm-sdm/v2/{suPI}/am-data<br/>Authorization: Bearer {access_token}
    P->>P: 验证 JWS 签名(用NRF公钥)<br/>校验 aud==自身ID, scope匹配, exp未过期
    P-->>C: 200 OK (签约数据)
    Note right of P: 令牌缓存于 Producer 用于后续校验加速

需要强调一个常被忽略的设计细节:步骤②的令牌请求是"消费者 → NRF",而非"消费者 → 生产者"。令牌由 NRF 签发,但由生产者验证。这意味着生产者必须信任 NRF 的签名(持有 NRF 公钥),而消费者只需信任 NRF 这一个授权点即可对接全网任意生产者——这就是"信任集中、对接解耦"的核心收益。

4.3 Access Token 请求/响应的 IE 结构

令牌的请求与响应由 TS 29.510 §5.4.2.2 定义,对应 OpenAPI 中的 AccessTokenReq 与 AccessTokenRsp。其字段结构如下:

flowchart LR
    REQ["AccessTokenReq<br/>(POST /oauth2/token)"]:::req --> R1["grant_type<br/>= client_credentials (必填)"]
    REQ --> R2["nfInstanceId<br/>消费者NF实例ID (必填)"]
    REQ --> R3["scope<br/>申请的服务范围 (必填)<br/>如 nudm-sdm"]
    REQ --> R4["nfType / targetNfType<br/>消费者/生产者类型"]
    REQ --> R5["targetNfInstanceId<br/>目的NF实例ID"]
    REQ --> R6["requesterPlmn / targetPlmn<br/>源/目的 PLMN"]
    RSP["AccessTokenRsp"]:::rsp --> S1["access_token<br/>JWS 紧凑序列化签名"]
    RSP --> S2["token_type<br/>= Bearer"]
    RSP --> S3["expires_in<br/>有效期(秒)"]
    classDef req fill:#e8f0fe,stroke:#1a73e8;
    classDef rsp fill:#fce8e6,stroke:#d93025;
IE 参数 必填 含义 安全作用
grant_type 是 固定 client_credentials,即客户端凭证模式 声明授权模式,无需用户参与
nfInstanceId 是 发起方 NF 实例 UUID 令牌主体(sub/client_id)来源
scope 是 申请的 NF 服务名(空格分隔可多项) 最关键的授权依据,限定可调用服务
targetNfInstanceId 否 目的 NF 实例 ID 收窄令牌受众,防止令牌被转用于其他实例
nfType / targetNfType 否 源/目的 NF 类型 便于 NRF 做策略校验
requesterPlmn / targetPlmn 否 源/目的 PLMN 标识 漫游场景下区分本网与拜访网
access_token 是 JWS 紧凑序列化的签名 JSON 实际的授权凭证,放入 Authorization 头
token_type 是 固定 Bearer 声明令牌使用方式
expires_in 否 有效期(秒) 控制令牌生命周期,默认常见 3600s

grant_type 取 client_credentials 是经过深思熟虑的选择:SBI 是机器对机器(M2M)调用,不存在"终端用户同意"环节,因此采用客户端凭证模式——消费者 NF 用自己的身份(mTLS 证书)直接换取令牌,绕开了授权码(authorization code)那套面向人类用户的交互流程。这既符合 OAuth2 语义,又契合 5GC 全自动的网内通信场景。

4.4 Access Token 的 JWT Claims 结构

access_token 并非随机字符串,而是一个经 JWS(JSON Web Signature)签名后的 JSON 对象,其载荷(payload)即 AccessTokenClaims。解码后的结构如下:

flowchart TB
    J["JWS = Header.Signature.Payload<br/>签名算法: RS256 / ES256"]:::jwt
    J --> C1["iss (issuer)<br/>签发者 = NRF 实例ID"]
    J --> C2["sub (subject)<br/>消费者 NF 实例ID"]
    J --> C3["aud (audience)<br/>生产者 NF 实例ID/类型"]
    J --> C4["exp (expiration)<br/>过期时间戳"]
    J --> C5["iat (issued at)<br/>签发时间戳"]
    J --> C6["scope<br/>授权的服务范围"]
    J --> C7["client_id<br/>消费者 NF 实例ID"]
    J --> C8["jti (JWT ID)<br/>令牌唯一标识(防重放)"]
    classDef jwt fill:#fef7e0,stroke:#f9ab00;

几个 claim 的安全意义值得逐条点明:

五、令牌生命周期:状态转换

OAuth2 令牌并非永久有效,其状态机如下。理解这套转换对排查"间歇性 401"至关重要:

stateDiagram-v2
    [*] --> 未获取: NF 启动/首次调用
    未获取 --> 申请中: POST /oauth2/token
    申请中 --> 有效: 200 OK (含 expires_in)
    申请中 --> 未获取: 400/401 (证书/scope 错误)
    有效 --> 有效: 命中本地缓存<br/>直接复用(剩余>阈值)
    有效 --> 申请中: 接近过期/收到401<br/>主动刷新
    有效 --> 失效: 到达 exp
    有效 --> 撤销: NRF 侧吊销(如NF注销)
    失效 --> 申请中: 重新申请
    撤销 --> 未获取: 清除本地缓存
    note right of 有效
        生产者也会缓存令牌→
        调用结果,加速校验
    end note

实践中,消费者 NF 通常本地缓存令牌并在剩余有效期低于阈值(如 10%)时提前刷新,避免每次服务调用都回溯 NRF 造成风暴;生产者 NF 也会缓存"令牌→校验结果"映射以加速验签。expires_in 的取值是性能与安全的权衡:过短增加 NRF 信令压力,过长放大泄露后的风险窗口。

六、与 SEPP/N32 的边界关系(易混淆点)

很多工程师会把"SBI 消息层安全"与"SEPP 跨域 N32 安全"混为一谈,二者其实分属不同层级:

对比维度 SBI OAuth2/JWT(§13.3) SEPP N32(§13.4 / TS 33.501)
适用场景 同一 PLMN 内 NF 间 跨 PLMN 漫游(hPLMN ↔ vPLMN)
信任锚 本网 NRF 双方 SEPP 协商(N32-c/N32-f)
保护对象 SBI 业务报文体 跨域 N32 信令(含敏感字段加密)
签名/加密 JWT 签名(完整性为主) N32-f 端到端 + 应用层加密
是否被中间节点解密 否(端到端 JWT 贯穿) SEPP 间有 MSRP/PRINS 等处理

关键认知:当漫游 NF 间发生 SBI 调用时,OAuth2/JWT 与 SEPP N32 是叠加生效的——SEPP 在网络域边界做传输保护与敏感字段重写,而 JWT 依然在两端 NF 之间端到端成立,SEPP 无法伪造 vPLMN AMF 的令牌来冒充它。这正是双层架构在跨域场景下的价值。

七、抓包识别:如何在 Wireshark 里认出这条链

在 5GC 抓包时,识别 OAuth2 令牌链非常直观:

  1. 令牌申请:POST /oauth2/token,Content-Type: application/x-www-form-urlencoded,body 形如 grant_type=client_credentials&nfInstanceId=xxx&scope=nudm-sdm&targetNfType=UDM。
  2. 令牌响应:200 OK,Cache-Control: no-store、Pragma: no-cache(强制不缓存,安全要求),body 是 JSON {"access_token":"eyJhbGciOi...", "token_type":"Bearer", "expires_in":3600}。
  3. 服务调用:随后 NF Consumer 的业务请求 HTTP 头携带 Authorization: Bearer eyJhbGciOi...。
  4. JWT 解码:access_token 以 eyJ 开头(base64url 的 {"alg":...} 头),可在 jwt.io 等工具拆出三段,payload 中可见 iss/sub/aud/scope/exp。

典型故障点与排错思路:

常见问题

Q1: 既然已经有 mTLS,为什么还要 OAuth2/JWT 这一层? A: mTLS 是逐跳(hop-by-hop)的,只能证明连接两端身份并加密管道,无法表达"对这个具体服务/数据有没有授权",也无法在报文经过代理/SEPP 时保证端到端完整性。OAuth2/JWT 是端到端的,弥补了授权粒度与跨中间节点的完整性两个缺口。二者是叠加而非替代关系。

Q2: scope 和 aud 分别限制什么? A: aud(audience)限制令牌能给哪个 NF 实例用(绑定目的方,防挪用);scope 限制令牌能调用哪个服务(绑定业务能力,防越权)。一个绑定了 UDM 实例的 nudm-sdm 令牌,既不能拿去调 PCF,也不能拿去调 UDM 的 nudm-ueau。

Q3: 生产者如何验证 JWT 签名?需要每次都连 NRF 吗? A: 不需要。生产者本地预置/定期获取 NRF 的公钥(JWK Set),验签在本地完成;只有首次或公钥轮换时才需与 NRF 同步公钥。生产者还会缓存"令牌→校验结果"以加速重复请求的判定。

Q4: 漫游场景下,vPLMN 的 AMF 能否用本网 NRF 签发的令牌调 hPLMN 的 UDM? A: 视运营商策略而定。通常跨 PLMN 调用经 SEPP(N32)完成传输保护与路由,OAuth2 授权策略可允许或拒绝跨域令牌(取决于 hPLMN 是否信任 vPLMN NRF 及其 scope 策略)。关键在于 hPLMN UDM 侧的 aud 与公钥信任配置。

Q5: 令牌泄露会有什么后果? A: 由于令牌绑定了 aud(特定生产者实例)和 exp(短有效期),且生产者侧可基于 jti 防重放,泄露令牌的爆炸半径被显著限制——只能用于指定生产者、指定 scope、且很快过期。配合 mTLS,攻击者即便拿到令牌也无法建立可信连接,实现了深度防御。

参考来源

  1. 3GPP TS 33.501 V18.10.0 — Security architecture and procedures for the 5G system — §13 Security of the SBA(13.2 传输层、13.3 消息层、13.4 网络域与跨 PLMN)
  2. 3GPP TS 29.510 — Network Function Repository Services; Stage 3 — §5.4 Nnrf_AccessToken 服务(令牌请求/响应、§5.4.2.2.3 多 NRF 中间令牌请求)
  3. 3GPP TS29510_Nnrf_AccessToken.yaml (OpenAPI) — AccessTokenReq/AccessTokenRsp 字段与 JWS 紧凑序列化定义
  4. free5GC — Introduction to OAuth2 Procedure — 基于 TS 33.501 §13.3.1 的 NF-NRF 授权流程实现解读
  5. free5GC — Authentication Mechanism in NRF: What Is OAuth? — OAuth2 在 SBI 中的角色映射与图解

本文由「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学通信知识星球海报-扫码加入