ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

UDS 27服务安全访问调试:NRC 35/36/37 触发条件与排查方法

UDS 27服务安全访问调试:NRC 35/36/37 触发条件与排查方法 调试 UDS 诊断服务的时候27 服务SecurityAccess安全访问一直是“重灾区”。明明种子拿到了密钥发送过去ECU 却回一个7F 27 35再试两次直接变成7F 27 36第三次想继续又被7F 27 37挡在外面。这三个负响应码在 27 服务调试中最常见也最容易让人一头雾水。本文会把 27 服务的种子/密钥交互流程、NRC 35/36/37 的触发条件、背后机制、报文特征和排查思路完整拆开。文章定位是“速查手册 实战笔记”既适合刚接触 UDS 的测试工程师也适合正在开发诊断仪、诊断脚本的嵌入式工程师。1. 27 服务基础安全访问的完整交互流程1.1 27 服务是做什么的在 UDSUnified Diagnostic Services统一诊断服务协议里27 服务用于实现 ECU 的“安全访问”。为什么要加一层安全访问因为 ECU 里面很多关键操作比如写入校准数据、刷写程序、读取敏感数据、执行特殊测试不能允许外部诊断仪随便执行。于是 ECU 会在执行这些受限操作前要求诊断仪先完成“解锁”也就是通过 27 服务证明自己持有合法密钥。简单理解就是诊断仪向 ECU 请求种子ECU 返回一个动态种子诊断仪根据种子计算密钥密钥校验通过后ECU 解锁受限功能密钥校验失败ECU 拒绝并返回负响应码。这样做的好处是密钥不会像固定密码那样不变。每次生成不同种子对应不同密钥即使有人截获了当前请求也不能直接重放。1.2 负响应码NRC机制UDS 的响应分为正响应和负响应。当 ECU 成功执行请求时返回SID 0x40的报文例如 27 服务成功就是0x67。当 ECU 无法执行请求时返回7F SID NRC的报文其中7F是负响应固定服务 ID第二个字节是被拒绝的服务 ID比如0x27表示这是 27 服务的负响应第三个字节是 NRCNegative Response Code也就是负响应码用来告知具体失败原因。例如7F 27 35的含义就是27 服务请求未通过原因是0x35密钥无效。在诊断工具或日志里有时也会看到十进制的53、54、55分别对应0x35、0x36、0x37。1.3 27 服务的请求子功能约定按照 ISO 14229 的常见约定27 服务使用成对子功能来区分“请求种子”和“发送密钥”子功能含义说明0x01请求种子请求安全等级 1 的种子0x02发送密钥发送安全等级 1 的密钥0x03请求种子请求安全等级 2 的种子0x04发送密钥发送安全等级 2 的密钥0x05请求种子请求安全等级 3 的种子0x06发送密钥发送安全等级 3 的密钥不同 OEM 可能在这个基础上做扩展例如自定义更高安全等级、自定义种子长度、自定义种子返回格式等。所以在排查 NRC 之前一定要先确认当前项目的诊断规范里如何定义子功能。很多0x35的案例根源就是诊断仪用错了安全等级。1.4 内部状态与计数机制理解 NRC 35/36/37必须先理解 ECU 在 27 服务内部维护的几个状态当前安全等级决定请求种子的等级、密钥算法、访问权限当前种子值每次请求种子后ECU 会生成一个新种子并记录到内部变量种子生成时间用来判断种子是否过期连续失败次数每次发送密钥失败都会增加计数锁定状态和时间戳当失败次数达到上限ECU 进入锁定状态并记录锁定起始时间。这些状态共同决定了 ECU 面对 27 服务请求时到底返回哪一个 NRC。2. NRC 0x35invalidKey深度解析2.1 标准定义与触发条件NRC 0x35 的英文名称是invalidKey中文意思是“密钥无效”或“密钥不正确”。在 ISO 14229 标准中它的核心触发条件可以概括为ECU 收到的密钥与内部根据当前种子计算出的期望密钥不匹配。也就是说当诊断仪执行发送密钥子功能时ECU 对收到的密钥进行校验发现对不上于是返回7F 27 35。从业务层面看这是“安全校验失败”。它说明 ECU 已经正常收到请求也允许在当前节点做安全访问问题出在密钥计算这一环。通常这不是通讯链路的问题而是 seed-key 算法、数据格式或者使用姿势的问题。2.2 常见根因分析0x35是三个 NRC 里最复杂的因为可能的原因非常多。第一seed-key 算法错误。不同 OEM甚至同一 OEM 的不同控制器密钥算法都可能不一样。常见算法包括查表法、异或变换、CRC、AES、自定义散列等。如果诊断仪实现的算法和 ECU 侧不是一套那么无论发什么密钥都会返回0x35。第二字节序处理错误。当种子是 4 字节数据时CAN 帧里看到的顺序可能是A1 B2 C3 D4但算法要的可能是把A1 B2 C3 D4组装为0xA1B2C3D4也可能要大小端交换后组装。发送密钥时同样存在字节序问题。很多脚本从一个平台移植到另一个平台就是字节序没对应上导致始终无法解锁。第三种子过期。部分 ECU 对种子设置时效性比如种子只在 1 到 10 秒内有效或者只要请求种子之后又执行了其他诊断请求种子立即失效。客户端拿到种子后如果先做了别的服务再回来发送密钥就可能被判定密钥无效。第四安全等级错位。请求种子时用的是等级 1发送密钥时却发到了等级 2或者代码里安全等级写死换了控制器后等级定义变了。这类问题在报文上看不太出来必须仔细核对子功能映射。第五密钥长度或填充错误。有些 ECU 对密钥长度有严格要求比如密钥必须补齐到 8 字节有些则对填充字节有特定要求。多发一个填充字节、少发一个密钥字节都可能导致校验失败。2.3 排查步骤当持续收到7F 27 35时建议按下面的顺序排查抓取完整诊断日志确认请求种子和发送密钥的报文内容不能只看工具弹窗提示对照 OEM 诊断规范确认子功能等级和密钥长度定义用同一组种子在仿真环境里运行 ECU 侧算法看计算结果与诊断仪是否一致检查字节序特别是种子或密钥长度大于 4 字节的场景检查两次请求之间是否插入了其他诊断服务尽量保证 27 服务流程连续执行确认 ECU 是否要求在指定会话默认会话、扩展会话或编程会话下执行安全访问。一个实用技巧如果测试台架 ECU 支持打开内部日志可以把 ECU 侧的密钥计算中间结果一起打印直接比较是哪一个步骤开始不一致。如果只能做黑盒测试建议多采集几组种子和错误响应分析算法变化规律缩小偏差范围。3. NRC 0x36exceedNumberOfAttempts深度解析3.1 标准定义与触发条件NRC 0x36 的英文名称是exceedNumberOfAttempts意思是“超过尝试次数”。它表示ECU 检测到连续失败的安全访问尝试次数已经超过允许的最大值。这是 ECU 的防护机制。如果没有次数限制攻击者就可以不断猜测密钥安全访问形同虚设。限制次数后即使攻击者持续发送错误密钥ECU 也会在达到阈值后拒绝继续尝试。常见的策略是连续失败 3 次后锁定具体次数由 OEM 定义。比如前两次错误密钥返回0x35第三次错误密钥直接返回0x36。有些 ECU 会从第二次失败开始进入冷却计时具体行为需要以规范为准。3.2 计数器的复位条件理解0x36的关键是弄清楚“失败计数什么时候归零”。不同 ECU 规则不同常见情况有成功通过一次安全访问后复位ECU 重新上电后复位进入冷却时间结束后自动复位切换到其他安全等级时复位失败计数持久化存储断电后依然保留。如果 ECU 把失败计数保存在非易失存储中那么断电重上电也不能清除锁定状态。这时只能等待冷却时间或者通过更高权限的安全机制解除。最稳妥的做法是确认 ECU 诊断文档中的具体描述。3.3 常见场景与处理建议0x36常出现在以下几种场景测试脚本里密钥算法写错连续请求多次自动化测试没有处理0x35发现密钥错误后继续循环重试多个诊断设备同时访问同一个 ECU其他设备已经触发锁定手动调试时频繁切换安全等级或算法导致失败累加。遇到0x36后建议立即停止重试。重试没有任何意义只会让冷却时间刷新甚至扩大锁定范围。正确做法是先排查连续失败的根本原因修复算法或参数再考虑如何解除锁定。4. NRC 0x37requiredTimeDelayNotExpired深度解析4
返回列表