1. SecurityAccess并不是“防盗锁”,而是诊断权限的闸门
1.1 27服务保护的是哪一层
做UD S诊断的人,几乎每天都在跟一串SID打交道:10会话控制、19读取DTC、22按ID读数据、2E按地址写数据、27安全访问、28通信控制、31例程控制、34/36/37刷写流程……但很多人对27的理解其实停留在“发个密钥就能解锁”的层面。真正在测试台架或实车上排查问题的时候,才发现它跟整车状态、会话控制、时序要求、尝试次数全部绑在一起,报错的时候连0x35、0x36、0x37都分不清。
SecurityAccess,也就是ISO 14229-1里定义的0x27服务,从名字上看是“安全访问”,但它保护的并不是整车的防盗锁,而是ECU内部一类“受限制的诊断功能”。大家可以这样理解:诊断仪跟ECU之间的普通对话,比如问一下软件版本、读一下故障码,属于对外开放的窗口;而写数据、标定、刷写程序、执行某些特殊例程,属于需要权限的内部房间。27服务就是那把进入内部房间的钥匙,准确地说,是“验证诊断仪是否有资格拿到钥匙”的门禁系统。
UDS诊断协议把诊断服务分成了几大类:10、3E这类负责通信和会话状态管理;19、14这类负责DTC的读与清;22、2E这类负责数据读取和写入。27服务属于“access”类别,专门负责权限控制。它在整个uds诊断流程里的位置非常特殊——不能直接产生业务效果,但没有它的许可,很多业务效果根本无法触达。打一个不精确但好记的比方:19服务是“你去查一下告警记录”,27服务是“你先证明你有权限去查告警记录”。前者是业务,后者是安全边界。
我在实际项目里见过不少新入行的同事,上来就对着诊断调查表找“27=SecurityAccess”,然后直接往报文里塞种子、密钥。等到ECU回一个7F 27 35,才发现自己连安全等级对应的子功能都还没理清楚。所以说,这份速记笔记首先要解决的不是“怎么发送27”,而是“27服务到底立在哪个环节、它后面托管了哪些权限”。
1.2 过了27服务才能碰哪些服务
要判断一个诊断功能是否需要先过27服务,最直接的办法是去读ECU的诊断规范或ODX文件,而不是靠猜。但大体上可以按风险来分级:凡是“只读不写”的,普遍不需要安全访问;凡是“会改变ECU内部状态、需要掉电保存、可能影响车辆行为”的,大概率需要安全访问。
举几个最常见的例子:22服务读VIN、读序列号、读版本号,基本不受27保护;2E服务写VIN、写配置字、写生产参数,通常会要求先完成安全访问;31服务里的例程控制,比如“擦除Flash”“复位DTC”“执行自学习”,是否要求安全访问,取决于例程编号对应的功能;34/36/37这一组刷写会话,几乎必然要求先通过安全访问,否则ECU不会接受下载请求。
还有一个容易被忽略的点:刷写或标定过程中,27服务通常不是只过一次,而是可能要按不同安全等级过多次。比如某些ECU在扩展会话下先做一次安全访问,允许写普通参数;进入编程会话后,又会用另一个安全等级验证刷写权限。这两个等级对应两个不同的子功能对,密钥算法也可能完全不同。
所以,我平时看诊断需求时,习惯先把“哪些服务需要解锁”列成一张矩阵。矩阵左边是SID和服务名,右边是安全等级、对应子功能、是否需要非默认会话、是否限定物理寻址、超时要求。这张矩阵看起来简单,但能有效避免“代码里把27写死成01/02,结果遇到需要05/06的控制器直接失败”这种低级事故。
1.3 安全等级与“一把钥匙开一把锁”
ISO 14229-1并没有规定ECU内部必须划分多少个安全等级,它只提供了等级编号的编码规则。实际项目实施中,OEM通常会根据产品需求自行定义:有的ECU只有一个等级,只要过了一道门后面都通;有的ECU把参数写入、例程执行、刷写分别划到不同等级,每个等级必须单独解锁。
这里的编码规律先记住:奇数子功能用于请求种子,偶数子功能用于发送密钥。也就是说,0x01/0x02是一对,0x03/0x04是一对,0x05/0x06是一对,0x07/0x08又是一对。每一对对应一个安全等级。
安全等级高低并不一定按数字大小排,0x05/0x06不一定比0x03/0x04权限更高,这完全是OEM内部定义。有些ECU把0x01/0x02作为普通标定解锁,0x03/0x04作为Bootloader刷写解锁;也有些ECU反过来。所以不要在国内A项目里习惯了“01去请求种子、02发密钥”,就直接套用到B项目的ECU上,还是要查对照表。
在uds诊断中信息安全相关的讨论里,经常有人纠结“种子是随机数吗”“如果种子可预测,安全访问不就形同虚设吗”。严格说,标准没有强制种子必须真随机,它只要求“使访问者无法通过简单重放上一次的响应来获得访问权限”。很多ECU在开发阶段为了便于台架测试,甚至会用固定序列或与时间相关的伪随机数作为种子。而在量产ECU里,种子通常由硬件安全模块生成,至少保证每次上电后的数值序列不可预测,防止攻击者直接录一段“27 01抓种子、27 02回密钥”的报文反复播放。
我一直跟团队强调一句话:27服务解决的是“授权入口”问题,而不是“绝对防盗”问题。真正的密钥算法、密钥存储、算法运行环境,才决定这套uds诊断信息安全体系的上限。车载诊断开发里,千万不要把SecurityAccess当成银弹。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 一次握手的完整速记:种子当考题,密钥当答卷
2.1 先记死请求格式:27 + 子功能
UDS诊断协议里的27服务,报文格式非常短,核心就是“SID + SubFunction + 数据”。随便翻一下ISO文档就能看到,27这个服务没有7F之外的正响应条件,也不需要像31服务那样先定义一个例程编号再决定后续长度。
请求种子时,诊断仪发出的诊断请求通常是:
text复制27 01
其中0x27是服务ID,0x01是子功能,表示“请求安全等级为1的种子”。如果ECU认为当前条件允许,它会回复:
text复制67 01 1A 2B 3C 4D
0x67是正响应SID,等于请求SID加0x40,这是UDS协议的统一特征;第二个字节是子功能回显,仍为0x01;后面的1A 2B 3C 4D就是ECU给出的种子数据。种子长度并不是固定的,常见的有2字节、4字节,也有部分ECU用更长或者更短的种子,具体定义以车型的诊断规范为准。
发送密钥时,报文变成:
text复制27 02 9E 81 76 90
