1. 从一个让人挠头的鉴权日志说起前阵子帮一个做核心网测试的朋友看问题他给我截了一段信令流程指着其中一条消息问我“这个SUCI到底是个啥为什么终端第一次注册的时候发的是它后面再注册又变成另一个东西了”我当时看了一眼发现他抓的包里初始注册请求里带的用户标识是一长串看起来像加密过的字符串而后续的注册更新里用的却是另一套格式。这个问题其实在5G核心网的学习和测试中非常典型很多人第一次接触SUCI的时候都会懵——它和SUPI、GPSI、5G-GUTI这几个标识符之间的关系到底是什么为什么5G要专门设计这么一个东西出来。如果你正在做5G核心网的协议开发、测试验证或者是在学习5G安全架构那SUCI这个概念是绕不过去的。它不是一个可有可无的补充字段而是5G用户身份隐私保护体系里的核心枢纽。这篇文章我会从实际的信令流程出发把SUCI的来龙去脉、结构组成、生成逻辑、在协议栈中的位置以及实际测试中容易踩的坑全部拆开讲清楚。不管你是刚入行的小白还是已经做过几个项目的工程师应该都能从中找到对自己有用的东西。2. SUCI到底解决了什么问题从SUPI裸奔说起2.1 4G时代遗留的身份暴露隐患要理解SUCI为什么存在得先看它的前身SUPI。SUPI全称是Subscription Permanent Identifier翻译过来叫“用户永久标识符”你可以把它理解成用户在移动网络里的“身份证号”。在4G时代这个身份证号就是IMSI它由MCC、MNC和MSIN三部分组成总共不超过15位数字。问题在于4G网络在空口传输IMSI的时候很多时候是明文发送的。也就是说只要有人拿一个伪基站或者嗅探设备在空口上抓包就能直接拿到用户的IMSI。拿到IMSI意味着什么意味着攻击者可以追踪这个用户的位置可以关联这个用户在不同时间不同地点的活动轨迹甚至可以用这个IMSI去伪造身份发起攻击。这在国际上已经被讨论了很多年也是隐私保护领域的一个老大难问题。4G时代虽然也引入了一些临时标识来缓解这个问题比如TMSI和GUTI但首次接入的时候仍然需要发送IMSI这个窗口期就是隐私泄露的高风险时段。2.2 5G的解题思路永久标识也要加密5G在设计之初就把用户隐私保护提到了一个很高的优先级。3GPP在TS 33.501里明确定义了SUCI的概念全称是Subscription Concealed Identifier即“用户隐藏标识符”。它的核心思路很直接既然SUPI在空口上明文传输不安全那我就把它加密之后再传。网络侧收到加密后的SUCI再通过解密还原出SUPI然后走后续的鉴权流程。这个思路听起来简单但实现起来涉及一套完整的密码学机制。SUCI不是简单地把SUPI做一次哈希或者对称加密就完事了它用的是基于公钥的加密方案而且要考虑不同运营商的密钥管理、不同终端的计算能力、以及漫游场景下的互操作性。这些约束条件叠加在一起就形成了SUCI现在这套看起来有点复杂但逻辑自洽的结构。2.3 SUCI和SUPI的对应关系这里需要明确一个关键点SUCI和SUPI是一一对应的但SUCI本身不是固定不变的。同一个SUPI用不同的公钥加密或者用不同的加密方案会生成不同的SUCI。这就解释了为什么我朋友在抓包的时候看到初始注册和后续注册用的标识不一样——因为网络侧可能会在鉴权过程中下发新的公钥或者指示终端使用不同的加密方案终端下次生成SUCI的时候就会用新的参数。这种设计的好处是增加了攻击者关联的难度。如果SUCI是固定不变的那攻击者虽然拿不到SUPI但仍然可以通过固定的SUCI来追踪用户。而SUCI可变之后攻击者就无法通过简单的标识符关联来追踪同一个用户了。当然这种可变性也给网络侧的测试和排错带来了一些麻烦后面我会专门讲这部分。3. SUCI的组成结构逐字段拆解3.1 整体格式概览SUCI在协议里的定义是一个包含多个字段的结构体不是简单的一个字符串。根据3GPP TS 23.003的定义SUCI的组成包括以下几个部分SUCI类型SUCI Type、归属网络标识Home Network Identifier、路由指示Routing Indicator、保护方案标识Protection Scheme Identifier、归属网络公钥标识Home Network Public Key Identifier、以及方案输出Scheme Output。这六个部分各有各的作用缺一不可。SUCI类型用来区分不同的SUCI格式目前主要用的是类型0和类型1。归属网络标识就是MCC和MNC的组合告诉网络这个用户属于哪个运营商。路由指示是一个0到4位的数字用来帮助网络侧把鉴权请求路由到正确的UDM或者AUSF。保护方案标识指明用的是哪种加密算法比如是ECIES还是其他方案。公钥标识告诉网络侧用的是哪把公钥来加密的。最后的方案输出就是加密后的实际数据包含了MSIN和可能的其他信息。3.2 归属网络标识与路由指示的配合归属网络标识这部分比较好理解就是MCC加MNC比如46000代表某个运营商的网络。但路由指示这个字段就有点意思了。它的作用是在归属网络内部做路由因为一个大运营商可能有很多个UDM实例网络需要知道把这个鉴权请求发给哪个UDM。路由指示的值通常是由运营商自己规划的终端在生成SUCI的时候会按照USIM卡里配置的值来填。这里有一个实际测试中容易忽略的点路由指示的默认值通常是“0”表示没有特定的路由需求网络侧会按照默认规则来处理。但在一些复杂的网络部署里运营商可能会给不同的用户群体分配不同的路由指示值这时候如果测试终端的USIM卡配置不对就会导致鉴权请求被路由到错误的UDM表现为鉴权失败或者超时。我在实际项目里就遇到过因为路由指示配置错误导致初始注册成功率只有一半的情况排查了很久才定位到这个问题。3.3 保护方案标识与公钥标识的取值逻辑保护方案标识是一个0到255的值目前标准定义的主要有几种0表示空方案也就是不加密直接传SUPI的MSIN部分1表示用ECIES方案2表示用另一种基于椭圆曲线的方案。实际商用网络里最常见的是方案1也就是ECIES。公钥标识是一个0到255的值用来区分同一个运营商可能有多把公钥的情况。比如运营商可以做密钥轮换用不同的公钥标识来区分新旧密钥。这两个字段的取值逻辑是终端根据USIM卡里的配置和网络侧下发的策略来决定的。在初始注册的时候终端可能用的是USIM卡里预置的默认公钥和方案。但在鉴权过程中AUSF或者UDM可能会通过NAS消息下发新的公钥或者方案指示终端收到之后就会在后续的SUCI生成中使用新的参数。这就是为什么同一个用户在不同时间生成的SUCI会不一样。3.4 方案输出的数据结构方案输出是SUCI里最核心的部分它包含了加密后的用户标识信息。以ECIES方案为例方案输出包括几个子字段临时公钥Ephemeral Public Key、加密后的MSIN、以及消息认证码MAC。临时公钥是终端在加密时随机生成的每次生成SUCI都会变这也是SUCI可变性的来源之一。加密后的MSIN就是用临时私钥和归属网络公钥做密钥协商后加密得到的。MAC用来保证数据的完整性防止被篡改。这个结构的设计思路是即使攻击者拿到了SUCI没有归属网络的私钥也无法解密出MSIN。而且由于临时公钥每次都在变攻击者也无法通过SUCI来关联同一个用户。但这里有一个前提归属网络的私钥必须严格保密。如果私钥泄露了那所有用这把公钥加密的SUCI都可以被解密后果会很严重。所以运营商在密钥管理上需要有一套严格的流程。4. SUCI在信令流程中的实际位置4.1 初始注册流程中的SUCI终端开机之后第一件事就是发起初始注册。在这个流程里终端需要向网络侧表明自己的身份这时候用的就是SUCI。具体来说终端在生成Registration Request消息的时候会把SUCI放在5GS Mobile Identity这个IE里发出去。网络侧的AMF收到之后根据SUCI里的归属网络标识和路由指示把鉴权请求路由到正确的AUSF和UDM。这里有一个细节值得注意终端在初始注册时如果之前没有有效的5G-GUTI就必须用SUCI。如果之前有有效的5G-GUTI那可以先用5G-GUTI发起注册网络侧如果找不到对应的上下文会再让终端用SUCI重新发起。这个机制在协议里叫“GUTI重分配”或者“标识请求流程”。实际测试中如果测试卡里没有预置有效的5G-GUTI那每次注册都会走SUCI流程这时候就能在抓包里稳定地看到SUCI。4.2 鉴权过程中的SUCI更新初始注册之后网络侧会对终端进行鉴权。在鉴权流程中AUSF或者UDM可能会通过Authentication Request消息里的某个字段指示终端在后续的SUCI生成中使用新的公钥或者方案。这个机制在协议里叫“SUCI计算指示”它允许网络侧动态地更新终端的SUCI生成参数。这个设计的目的是为了支持密钥轮换和策略更新。比如运营商发现某把公钥可能已经不够安全了就可以通过这个机制让终端切换到新的公钥。终端收到指示之后会在下一次需要发送SUCI的时候使用新的参数。这就是为什么同一个用户在初始注册和后续注册中抓包看到的SUCI格式可能不一样。如果你在做测试的时候发现SUCI突然变了不要慌先检查一下是不是网络侧下发了新的计算指示。4.3 服务请求和切换场景中的SUCI在终端已经注册成功、建立了5G-GUTI之后后续的服务请求和切换流程里通常不会再发送SUCI而是用5G-GUTI来标识自己。5G-GUTI是网络侧分配的临时标识它只在当前注册区域内有效而且会定期更新。用5G-GUTI的好处是它不包含用户的永久标识信息即使被截获也无法直接关联到具体用户。但在某些特殊场景下SUCI仍然会出现。比如终端从5G网络移动到4G网络再回到5G网络的时候如果上下文丢失了可能就需要重新用SUCI发起注册。再比如网络侧发起了标识请求流程要求终端重新上报SUCI这时候也会在信令里看到SUCI。这些场景在实验室测试里可能不太常见但在外场测试或者漫游测试里就会遇到。5. 生成SUCI的完整计算链路5.1 从USIM读取参数终端生成SUCI的第一步是从USIM卡里读取必要的参数。这些参数包括SUPI的MSIN部分、归属网络标识、路由指示的默认值、以及默认的保护方案标识和公钥标识。这些信息通常存储在USIM卡的特定EF文件里终端通过APDU命令来读取。这里有一个实际开发中容易踩的坑不同厂商的USIM卡在EF文件的组织方式上可能有差异有些卡可能把路由指示和公钥标识存在不同的文件里有些卡可能用默认值。如果终端侧的读取逻辑写得不够健壮就可能读不到正确的参数导致生成的SUCI不符合网络侧的预期。我在一个项目里就遇到过因为USIM卡文件读取顺序不对导致路由指示读成了默认值0而网络侧期望的是非0值结果鉴权请求被路由到了错误的UDM。5.2 ECIES加密的具体步骤以最常用的ECIES方案为例生成SUCI的方案输出需要经过以下几个步骤。第一步终端生成一个临时密钥对包括临时私钥和临时公钥。这个密钥对是基于椭圆曲线的常用的曲线是secp256r1。第二步终端用临时私钥和归属网络的公钥进行ECDH密钥协商得到一个共享密钥。第三步用这个共享密钥派生出对称加密密钥和MAC密钥。第四步用对称加密密钥对MSIN进行加密得到密文。第五步用MAC密钥对密文和相关参数计算MAC。最后把临时公钥、密文和MAC拼接起来就是方案输出。这个过程涉及多次密钥派生和加密运算对终端的计算能力有一定要求。在实际测试中如果终端的加密模块实现有问题可能会导致生成的SUCI无法被网络侧正确解密。表现就是鉴权失败而且网络侧返回的错误原因可能比较模糊比如“用户未找到”或者“鉴权失败”不会直接告诉你SUCI解密失败。这时候就需要用专门的工具去分析SUCI的结构看看是哪个字段出了问题。5.3 不同保护方案的差异除了ECIES方案标准还定义了其他几种保护方案。方案0是空方案也就是不加密直接把MSIN明文放在方案输出里。这个方案主要是为了兼容一些特殊场景比如测试环境或者某些物联网设备。方案2是基于另一种椭圆曲线算法的方案具体细节在协议里有定义但实际商用网络里用得比较少。不同方案的选择会影响SUCI的长度和结构。方案0的SUCI最短因为方案输出就是MSIN本身。方案1的SUCI最长因为包含了临时公钥和MAC。在做协议一致性测试的时候需要针对不同的方案分别验证。如果测试仪表只支持方案1而终端配置的是方案0那就会出现不匹配的情况。所以在测试之前一定要确认终端和网络侧的方案配置是一致的。6. 实测中容易踩的坑与排查思路6.1 SUCI格式不匹配导致的鉴权失败这是最常见的问题之一。终端生成的SUCI格式和网络侧期望的不一致导致网络侧无法解析或者解密。具体表现可能是鉴权请求被拒绝或者网络侧返回“永久标识不可用”之类的错误。排查的时候首先要在抓包里找到Registration Request消息把里面的SUCI字段完整地提取出来然后按照协议定义逐字段检查。检查的顺序建议是先看SUCI类型对不对再看归属网络标识是不是和测试卡匹配然后看路由指示的值是否符合网络侧的规划接着看保护方案标识和公钥标识是不是网络侧支持的最后看方案输出的长度和结构是否合理。这个排查过程听起来简单但实际操作中如果没有一个趁手的解析工具光靠手工去数字节会非常痛苦。建议自己写一个小脚本把SUCI的十六进制字符串按照协议格式解析成可读的字段。6.2 公钥不匹配的隐蔽问题公钥不匹配的问题比格式不匹配更隐蔽因为SUCI的结构看起来完全正常但网络侧就是解不出来。这种情况通常发生在终端使用的公钥和网络侧期望的公钥不是同一把的时候。比如终端从USIM卡里读到了旧的公钥标识但网络侧已经轮换到了新的公钥这时候终端用旧公钥加密的SUCI网络侧用新私钥就解不开。排查这个问题需要对比终端侧和网络侧的公钥配置。终端侧的公钥标识可以从USIM卡里读出来网络侧的公钥标识可以从UDM或者AUSF的配置里查。如果两边不一致那就需要更新终端侧的配置。在实际项目里这种问题往往出现在测试卡没有及时更新或者网络侧做了密钥轮换但没有同步通知终端的情况下。6.3 路由指示配置错误的连锁反应路由指示配置错误的表现比较有迷惑性因为终端侧看起来一切正常SUCI也生成出来了但网络侧就是找不到用户。这是因为路由指示决定了鉴权请求被路由到哪个UDM如果路由指示指向了一个没有该用户数据的UDM那自然就找不到用户了。排查这个问题需要看网络侧的日志确认鉴权请求被路由到了哪个UDM然后对比该UDM上是否有测试卡的用户数据。如果路由指示的值和UDM的配置不匹配就需要修改终端侧的USIM卡配置或者网络侧的路由规则。这个问题的难点在于它涉及到终端和网络两侧的配合如果只盯着一边看很难定位到根因。6.4 抓包分析SUCI的实用技巧在实际测试中抓包分析是排查SUCI问题的主要手段。但SUCI在空口上是加密传输的普通的抓包工具可能只能看到加密后的数据。这时候需要用支持5G协议解析的专业工具比如一些信令分析仪或者协议测试仪表。这些工具可以把空口上的加密数据解密还原出NAS消息然后进一步解析出SUCI的各个字段。如果没有专业工具也可以从网络侧的日志入手。AUSF和UDM通常会记录收到的SUCI信息包括各个字段的值和解密结果。通过对比终端侧生成的SUCI和网络侧收到的SUCI可以快速定位是哪个环节出了问题。另外一些开源的5G核心网实现也提供了SUCI的解析和生成工具可以用来做交叉验证。7. 关于SUCI的几个常见误解7.1 SUCI不是永久不变的很多人第一次接触SUCI的时候会下意识地把它当成SUPI的加密版本认为同一个SUPI生成的SUCI是固定的。这个理解是不对的。SUCI的可变性是它的一大特点也是它比简单加密更安全的原因。每次生成SUCI的时候终端都会用新的临时密钥对所以即使SUPI和公钥都不变生成的SUCI也是不同的。这种可变性给网络侧带来了一定的计算负担因为每次收到SUCI都需要做一次解密运算。但相比于隐私保护带来的收益这个代价是值得的。在实际测试中如果你看到同一个测试卡在不同时间生成的SUCI不一样不要觉得奇怪这是正常现象。7.2 SUCI不等于5G-GUTISUCI和5G-GUTI都是用户标识但它们的用途和生命周期完全不同。SUCI是用来在初始注册时向网络侧表明身份的它包含加密后的永久标识信息。5G-GUTI是网络侧在注册成功后分配给终端的临时标识用来在后续的信令流程中替代SUCI减少空口上的敏感信息传输。简单来说SUCI是“我是谁”5G-GUTI是“网络认为我是谁”。SUCI只在需要的时候才发送比如初始注册或者标识请求流程。5G-GUTI则在每次服务请求和切换时都会用到。两者配合使用既保证了安全性又提高了效率。7.3 SUCI不只在初始注册时出现虽然初始注册是SUCI最常出现的场景但它并不是唯一场景。前面提到过在鉴权过程中网络侧可能要求终端更新SUCI参数在后续的注册更新中也可能用到SUCI。另外在一些异常场景下比如网络侧丢失了终端的上下文或者终端从异常状态恢复也可能需要重新发送SUCI。所以在做协议测试的时候不能只关注初始注册流程还要覆盖注册更新、服务请求、切换等各种场景确保SUCI在这些场景下的行为都符合预期。特别是SUCI参数更新后的行为需要重点验证因为这里涉及到终端和网络侧的参数同步问题。8. 从开发视角看SUCI的实现要点8.1 终端侧的实现注意事项如果你在做终端侧的协议栈开发SUCI的生成逻辑需要特别注意几个点。第一USIM卡参数的读取要健壮不能假设所有卡的文件结构都一样。第二临时密钥对的生成要符合规范随机数的质量直接影响安全性。第三加密运算的实现要正确特别是ECDH密钥协商和密钥派生部分任何一步出错都会导致SUCI无法被解密。第四要支持网络侧下发的SUCI计算指示能够动态更新公钥和方案参数。在实际开发中建议把SUCI的生成逻辑做成一个独立的模块方便单独测试和验证。可以先用已知的测试向量来验证加密结果的正确性然后再集成到完整的协议栈里。另外日志要打全把每次生成SUCI时用的参数都记录下来方便出问题的时候排查。8.2 网络侧的实现注意事项网络侧的实现重点是SUCI的解析和解密。AUSF或者UDM收到SUCI之后需要根据归属网络标识和路由指示找到对应的用户数据然后根据保护方案标识和公钥标识选择正确的私钥进行解密。解密成功之后还要验证MAC确保数据没有被篡改。网络侧的实现难点在于密钥管理。运营商可能有多把公钥和对应的私钥需要有一套机制来管理这些密钥的生命周期包括生成、分发、轮换和销毁。另外网络侧还需要支持SUCI计算指示的下发能够根据策略动态地指示终端更新参数。这些功能在标准里都有定义但具体实现起来需要考虑性能和可靠性的平衡。8.3 测试验证的关键用例无论是终端侧还是网络侧SUCI相关的测试用例都应该覆盖以下几个关键场景。第一初始注册时用SUCI标识验证网络侧能够正确解密和鉴权。第二鉴权过程中网络侧下发SUCI计算指示验证终端能够正确更新参数并在后续流程中使用新的SUCI。第三SUCI格式异常时的处理比如字段缺失、长度不对、方案不支持等验证网络侧能够正确拒绝并返回合适的错误原因。第四不同保护方案之间的切换验证终端和网络侧能够正确协商和使用不同的方案。这些测试用例在设计的时候要考虑到正常流程和异常流程的覆盖还要考虑到不同厂商设备之间的互操作性。在实际项目里互操作性问题往往是SUCI相关问题的重灾区因为不同厂商对协议的理解和实现可能有细微差异这些差异在单厂商测试中看不出来一到多厂商联调就暴露了。9. 我个人在实际操作中的几点体会做5G核心网测试这几年SUCI相关的问题我遇到过不少有几个体会比较深。第一个是不要假设USIM卡的配置是正确的。测试卡在多次使用之后里面的参数可能会被改写或者和网络侧的配置不同步。每次开始测试之前最好先读一遍卡里的关键参数确认和网络侧规划一致。第二个是抓包工具的选择很重要。普通的抓包工具只能看到加密后的数据对排查SUCI问题帮助有限。建议至少准备一套支持5G NAS解密的工具能省很多时间。第三个体会是关于日志的。终端侧和网络侧的日志都要打全特别是SUCI生成和解密过程中的关键参数比如用的公钥标识、方案标识、临时公钥等。这些信息在排查问题的时候非常有用。我见过一些实现为了省事日志里只打一个“SUCI生成成功”或者“SUCI解密失败”这种日志在出问题的时候基本帮不上忙。最后一个体会是SUCI的问题往往不是孤立的问题它可能涉及到USIM卡、终端协议栈、网络侧配置、密钥管理等多个环节。排查的时候要有全局视角不要只盯着一个点看。从终端到网络沿着信令流程一步步走把每个环节的输入输出都确认一遍大部分问题都能定位到根因。