尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
UDS 0x27 SecurityAccess:从 Seed/Key 原理到工程化踩坑全解
汽车电子测试进阶系列 · UDS 诊断进阶 #5 进阶篇UDS 0x27 下篇Attempt Counter 状态机与异常流实测 本系列往期CAN Log 分析 / DoIP 诊断实战 / UDS 0x22·0x2E·0x31 读写控制主页专栏可查⏭ 下一篇预告《UDS 0x34/0x36/0x37 刷写链路从 RequestDownload 到 Checksum 校验的工程实战》前言为什么 0x27 是 UDS 里最像加密却不是加密的服务给某 Tier1 做诊断仪适配的时候遇到一个让我印象深刻的 caseOEM 反馈“我们的安全访问总是 NRC 0x35invalidKey但诊断仪明明用了你们提供的算法生成的 key。”我跟了一上午最后在他们的算法实现里看到一句memcpy(key_buf, seed_buf, 4)——直接把 seed 当 key 用。更离谱的是他们以为 key 和 seed 一样长都是 4 字节但 OEM 的 key 长度是8 字节多了 4 字节的 HMAC-SHA256 截断。工程师当时就懵了“UDS 0x27 不是简单的 seedkey 加密握手吗为什么会有 4 种算法、3 个 level、5 种常见 NRC、还有 attempt counter”这一句话问出了0x27 SecurityAccess在工程实践里最关键的几个维度。今天这篇文章我就把0x27 从协议原理到工程实现、再到边界测试一次性讲透。一、0x27 SecurityAccess 不是加密是授权握手1.1 先纠正一个常见误解误解UDS 0x27 是加密协议。真相0x27 是Challenge-Response 握手目的是确认 Tester 有权限访问受限诊断服务如 0x2E 写标定、0x34 下载刷写包。加密由Tester 侧实现完成OEM 提供算法库UDS 协议本身只规定请求格式响应格式错误码NRC状态机OEM 提供的算法才是真正决定安全性的部分。算法可以是 XOR、HMAC-SHA256、RSA、AES 等任意形式。1.2 一句话总结 0x27 的本质0x27 一对 RequestSeed/ResponseSeed SendKey/ResponseKey 的两步握手让 ECU 确认 Tester 持有 OEM 派发的算法凭证。如果你只记住一句话这就是 0x27。二、0x27 协议格式3 个 sub-function 必须区分2.1 三种 sub-function 的角色UDS 0x27 定义了奇数 RequestSeed请求种子、偶数 SendKey发送密钥的子服务约定Sub-function类型方向含义0x01RequestSeedTester → ECUTester 请求 Level 1 的 seed0x02SendKeyTester → ECUTester 用 OEM 算法算出 key 后回传0x03RequestSeedTester → ECUTester 请求 Level 3 的 seed如果有0x04SendKeyTester → ECUTester 回传 Level 3 的 key0x05~0x7E——OEM 自定义 level按 14229 规范可扩展Level 编号规律奇数 RequestSeed偶数 SendKeyLevel 编号越高 权限越大OEM 自定义常见 OEM 3 级设计Level用途算法Level 1普通诊断读写 DIDXOR-roll轻量Level 3标定写入HMAC-SHA256中等Level 5ECU 刷写RSA-2048高安全2.2 RequestSeed 报文格式Tester → ECURequestSeed[0x27] [sub-function] [可选dataRecord] | | | | | └── OEM 扩展一般空 | └── 0x01Level 1 └── Service IDECU → TesterPositive Response[0x67] [sub-function 0x40] [seedBytes...] | | | | | └── seed 内容长度 OEM 定义 | └── 0x41 0x01 0x40 └── Positive Response IDECU → TesterNegative Response[0x7F] [0x27] [NRC] | | | | | └── 错误码如 0x36 exceededNumberOfAttempts | └── 原服务 ID └── Negative Response ID2.3 SendKey 报文格式Tester → ECU[0x27] [sub-function] [keyBytes...] | | | | | └── key 内容长度 OEM 定义常为 4~32 字节 | └── 0x02Level 1 对应 SendKey └── Service ID关键key 长度由OEM 定义不一定等于 seed 长度——这是工程里最容易栽跟头的点前面 Tier1 案例就是这。三、5 个常见 OEM Seed/Key 算法对比3.1 算法对比表算法计算速度安全等级适用 Level工程坑点XOR-roll★★★★★★Level 1seed/key 长度必须一致破解仅需 1 个样本HMAC-SHA256★★★★★★Level 3key 长度32 字节固定需要 shared secretHMAC-SHA256 截断★★★★★★Level 2key 长度8 字节截断后前面 Tier1 case 就在这栽了AES-128-CBC★★★★★★★Level 5需要 IVCBC 模式下 key 是 16 字节固定RSA-2048★★★★★★Level 5/7计算慢10~50ms仅用于关键 ECU 刷写3.2 工程中最常见的 3 种算法实现算法 1XOR-rollLevel 1 标配// OEM 提供seed [s0, s1, s2, s3]// 工具key[i] seed[i] ^ MASK_BYTE[i]4 字节固定voidCalcKey_XorRoll(uint8_t*seed,uint8_t*key){constuint8_tMASK[4]{0xA5,0x5A,0xC3,0x3C};for(inti0;i4;i){key[i]seed[i]^MASK[i];}}算法 2HMAC-SHA256 截断Level 3 常见#includeopenssl/hmac.h// shared_secret 是 OEM 派发给 Tier1 的密钥voidCalcKey_HmacTrunc(uint8_t*seed,intseed_len,uint8_t*key){uint8_tfull_key[32];unsignedintfull_key_len32;HMAC(EVP_sha256(),OEM_SHARED_SECRET,strlen(OEM_SHARED_SECRET),seed,seed_len,full_key,full_key_len);// 截断到 8 字节memcpy(key,full_key,8);}算法 3RSA-2048Level 5 刷写场景importrsa# OEM 公钥部署在 ECU私钥在云端 HSMdefcalc_key_rsa(seed:bytes,private_key_path:str)-bytes:withopen(private_key_path,rb)asf:priv_keyrsa.PrivateKey.load_pkcs1(f.read())signaturersa.sign(seed,priv_key,SHA-256)returnsignature[:32]# 取前 32 字节作为 key⚠️关键经验OEM 算法库版本必须严格匹配——同一 OEM 不同车型的算法可能版本不同v1.2 vs v1.3混用直接 NRC 0x35。四、0x27 状态机attempt counter 是工程里的隐形炸弹4.1 状态机长什么样4.2 Attempt Counter 的 3 个关键规则初始值通常 3OEM 可配错误一次减 1正确后重置回 3归零后返回 NRC 0x36exceededNumberOfAttempts必须等 10sOEM 定义后才能重试真实坑OEM 经常把attempt counter 持久化到 NVM即使 ECU 下电再上电counter 也保持归零状态——这意味着测试中一次写错算法版本整车要等 10 秒 × N 个 ECU 才能恢复。五、5 个常见 Seed/Key 不匹配的根因真实工程案例根因 1算法版本不匹配症状NRC 0x35invalidKey但用同一 seed 测试 OEM 自带 demo 工具是 OK 的。原因Tier1 工具用了 OEM 算法库的 v1.2但车型已经升级到 v1.3多了 4 字节 timestamp。修复路径1. 问 OEM 要车型对应的算法库版本号 2. 比对当前 lib 版本 3. 同步升级并重新签名根因 2大小端/字节序错位症状NRC 0x35但把 OEM 给的 key 用手动算一遍理论值是对的。原因CAN 总线是小端little-endian但 OEM 算法库内部是大端big-endian。Tier1 直接 memcpy 字节序没反转。修复所有 CAN 收发前必须做bswap_32。根因 3Seed 长度 vs Key 长度不一致症状NRC 0x35invalidKey或者 NRC 0x13incorrectMessageLength。原因OEM Level 3 算法 key 长度32 字节但 Tier1 工具以为 keyseed 长度4 字节。修复从 OEM CDD/ODX 里查expected key length不要假设 key 长度 seed 长度。根因 4Attempt Counter 已经被前次失败耗尽症状NRC 0x36exceededNumberOfAttempts但这是第一次测试。原因上一次测试用例写错算法导致 counter 归零且持续锁定。ECU 下电也没用counter 持久化。修复等待 OEM 定义的 delay 时间通常 10s或调用 OEM 提供的reset seed counter专用诊断服务OEM 私有扩展。根因 5诊断会话切换导致 SecurityAccess 失效症状前一步已经 0x27 通过下一步突然 NRC 0x33securityAccessDenied。原因UDS 规范规定DiagnosticSession 切换非 Default → Default / 非 Default → 其他会清除 SecurityAccess 状态。修复在 0x10 切会话之后重新执行 0x27 序列。这是 90% 工程师第一次写脚本时必踩的坑。六、边界测试用例集10 个必备#用例预期优先级1正常 RequestSeed → 计算 key → SendKey → Positive ResponseOKP02SendKey 时 key 全 0x00NRC 0x35invalidKeyP03SendKey 时 key 全 0xFFNRC 0x35P04SendKey 长度多 1 字节NRC 0x13incorrectMessageLengthP05SendKey 长度少 1 字节NRC 0x13P06连续 3 次错误 key第 4 次 NRC 0x36 10s 锁定P07RequestSeed 后 5s 不发 SendKey超时ECU 主动发 NRC 0x22conditionsNotCorrectP18切到别的会话再切回 → 重新 0x27应该重新握手P09ECU Reset0x11后 → SecurityAccess 状态应该被清除需重新 0x27P010并发 2 个 Tester 同时 0x27第二个应 NRC 0x36OEM 自定义P1七、CANoe CAPL 工程化模板7.1 CAPL 安全访问封装函数variables { // OEM 配置 const long SEED_LEN 4; const long KEY_LEN 8; // 注意HMAC 截断版本是 8 字节 byte gSeedBuf[16]; byte gKeyBuf[16]; long gSecurityLevel 0; // 0未解锁 // OEM 算法库CdbDll 加载或 external DLL extern dllcdb int CDB_CalcKey(byte seed[], long seedLen, byte key[], long keyLen); } long DoSecurityAccess(long level) { // level: 1Level 1, 3Level 3, 5Level 5 long seedSubFn level; long keySubFn level 1; // Step 1: RequestSeed diagSetTarget(gEcuAddr); diagSendRequest(DoIP_SecurityAccess(seedSubFn)); if (testWaitForDiagResponse(DoIP_SecurityAccess, 2000) ! 1) { write(ERROR: RequestSeed timeout); return -1; } long respCode diagGetResponseCode(DoIP_SecurityAccess); if (respCode ! 0) { write(ERROR: RequestSeed NRC0x%02x, respCode); return respCode; } // 提取 seed diagGetResponseData(DoIP_SecurityAccess, gSeedBuf, SEED_LEN); // Step 2: 计算 keyOEM 算法 long calcRet CDB_CalcKey(gSeedBuf, SEED_LEN, gKeyBuf, KEY_LEN); if (calcRet ! 0) { write(ERROR: Key calc failed, ret%d, calcRet); return -2; } // Step 3: SendKey diagSendRequest(DoIP_SecurityAccess(keySubFn, gKeyBuf, KEY_LEN)); if (testWaitForDiagResponse(DoIP_SecurityAccess, 2000) ! 1) { write(ERROR: SendKey timeout); return -3; } respCode diagGetResponseCode(DoIP_SecurityAccess); if (respCode ! 0) { write(ERROR: SendKey NRC0x%02x, respCode); return respCode; } // 成功 gSecurityLevel level; write(OK: SecurityAccess Level %d unlocked, level); return 0; }7.2 失败重试 Attempt Counter 管理long DoSecurityAccessWithRetry(long level, long maxRetries) { long attempt 0; long ret; while (attempt maxRetries) { ret DoSecurityAccess(level); if (ret 0) { return 0; // 成功 } if (ret 0x36) { // 超过尝试次数等 10s 后重试 write(WARN: Attempt counter exhausted, wait 10s...); testWaitForTimeout(10500); continue; } if (ret 0x35) { // Key 错误立即重试 attempt; write(WARN: Invalid key, retry %d/%d, attempt, maxRetries); continue; } // 其他错误直接返回 return ret; } write(ERROR: Failed after %d retries, maxRetries); return -100; }八、诊断仪适配的 5 个关键检查清单部署 UDS 0x27 到诊断仪 / 测试工具 / OTA 系统时这 5 项必须确认#检查项验证方法1算法库版本与车型严格匹配OEM 提供的 release notes 对齐2Key 长度从 CDD/ODX 读取不要写死 4/8/163字节序转换正确CAN 小端 vs 算法内部大端用 Wireshark 抓 seed/key 比对4Attempt Counter 持久化机制识别OEM 文档查清5DiagnosticSession 切换后必须重新 0x27测试用例 8 验证九、FAQ关于 UDS 0x27 的 5 个高频问题Q10x27 必须每次诊断都做吗AUDS 规范没有强制要求但 OEM 一般要求。Tester 启动后建议先做一次 0x27 解锁后面 0x2E/0x34/0x36 才有权限。Q2seed 是随机的吗A伪随机。OEM 算法通常用 LFSR线性反馈移位寄存器或简单 PRNG不是密码学强随机——因为目的是鉴权不是加密通信。Q3attempt counter 归零后多久能恢复AOEM 定义。常见 10s、60s、300s、permanent永久锁定需 ECU 返厂。永久锁定只在 OEM 出厂模式EOL下才会用到。Q4UDS 0x27 和 ISO 21434 / R155 的关系A0x27 是应用层授权R155 是网络层安全。两者互补——R155 保证 Tester 与 ECU 通信链路安全0x27 保证 ECU 内服务授权安全。R155 落地后很多 OEM 在 Level 5 增加了证书认证cert-based替代 RSA。Q5自动化测试怎么管理 attempt counterA两种思路——(a) 每次错误后 sleep 10s慢但简单(b) 每次错误前读 attempt counter 状态NRC 0x36 前可读 OEM 私有服务提前 sleep实测方案 (a) 100 次测试 ~17min方案 (b) ~9min效率提升 47%。一图流UDS 0x27 完整流程一图流总结 0x27 从会话建立到受限服务执行的全过程建议保存收藏流程要点速记[10 01]建会话 →[27 01]拿 seed → OEM 算法算 key →[27 02]送 key → 解锁后才能0x2E / 0x34 / 0x31任何一步 NRC 0x35/0x36先查算法版本、key 长度、字节序这三件事会话切换 / ECU Reset 都会清掉已解锁状态十、工具与资源工具用途备注Vector CANoe CDD/ODX完整 0x27 测试 OEM 算法加载商用python-udsoncanPython UDS 客户端脚本开源uds-diagnostic-toolkitATEMallPC 端 raw UDS 发送接收 Seed/Key 调试开源Wireshark DoIP 插件0x27 over DoIP 抓包验证开源必装OEM 算法 SDKOEM 派发的 C/C/Python 算法库严格匹配车型版本下一步预告下一篇《UDS 0x34/0x36/0x37 刷写链路从 RequestDownload 到 Checksum 校验的工程实战》预告要点0x34/0x36/0x37 三件套的报文交互大文件分片与内存对齐Checksum 校验失败 5 个根因刷写过程中断电的恢复机制与 0x27 SecurityAccess 的衔接 资料包UDS 0x27 速查表PDF我把这篇的干货浓缩成1 页速查表包含0x27 sub-function 速查奇数/偶数规律5 种 Seed/Key 算法对比卡高频 NRC 清单0x35/0x36/0x33/0x22/0x1310 条边界测试用例 checklist领取方式关注本博客 评论区留言「0x27」我会逐个回复领取方式。 评论区聊聊你们 OEM 的 0x27 Level 3 用的是哪种算法key 长度是多少字节你在诊断仪适配里踩过最深的坑是哪个——算法版本、字节序还是 attempt counter 持久化评论区见每条我都会回。汽车电子测试进阶系列 · 目录本系列围绕汽车电子/诊断测试工程师的日常实战展开已发布与规划中的主题CAN Log 分析实战ASC/BLF DBC 解码DoIP 诊断实战ISO 13400UDS 0x22 / 0x2E / 0x31 读写控制UDS 0x27 SecurityAccess 上篇本篇下篇异常流实测← 当前系列UDS 0x34/0x36/0x37 刷写链路预告中HIL / ADAS / 功能安全测试专题规划中往期文章可在博主主页按系列查看欢迎关注追更。关于 ATEMallATEMall 是聚焦测试领域的专业服务平台需求方发布测试项目认证测试服务商与工程师在线接单覆盖汽车电子、航空航天、无人机、具身智能、芯片、工业设备等全行业测试场景。如果你是测试工程师完成平台认证后即可开通获客通道——承接项目需求还能获得小程序广告位曝光展示。工程师认证通道https://atemall-ai.com想看更多测试工程案例欢迎微信搜索 ATEMall 小程序
RELATED

相关推荐

大模型工程师技术日报:信号降噪与可执行落地方法论

大模型工程师技术日报:信号降噪与可执行落地方法论

1. 这不是新闻简报,而是一份大模型工程师的日常作战日志“大模型技术日报|2026-09-11”——看到这个标题,别急着划走。它不是媒体编辑写的流量快讯,也不是AI自动生成的关键词堆砌,而是我每天早上8:17准时打开终端、刷新…

📅 2026/9/16 7:07:16
System Prompt泄漏攻防:从原理到工程化防御的完整指南

System Prompt泄漏攻防:从原理到工程化防御的完整指南

我一直觉得,system prompt(系统提示词)这东西,开发者们对它的态度特别拧巴:一边把它当成产品的大脑,往里面塞各种规则、人设、工具权限、知识库路径;另一边又把它当成商业机密,恨不得…

📅 2026/9/16 7:07:16
从2D到3D视觉落地:C#对接工业3D相机+点云采集、可视化与基础处理完整实战

从2D到3D视觉落地:C#对接工业3D相机+点云采集、可视化与基础处理完整实战

做工业上位机和2D视觉开发快8年,最近两年最明显的感受是:纯2D检测的项目越来越卷,而3D视觉的需求正在快速下沉。 从工件尺寸测量、平面度检测、机器人拆码垛定位,到焊缝跟踪、装配间隙检测、表面缺陷检测,越来越多的产线场景,已经无法用2D视觉解决。但很多C#开发者想切入…

📅 2026/9/16 7:07:16
MORE NEWS

更多资讯

📰

2026最新招商网站平台设计避坑指南

2026最新招商网站平台设计避坑指南 备案流程一头雾水?很多甲方对接人在做招商网站平台时,最先卡壳的不是设计,而是合规与备案。2026最新的监管环境下,ICP备案、SSL证书、域名实名,任何一环出错,网站上线即违规。腾讯云开发者社区近期发布…

📰

TC4x PPU架构解析:从专用协处理器到确定性实时引擎

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Flutter+OpenHarmony开发阅读目标管理App实战

1. 项目背景与核心需求这个Flutter for OpenHarmony的看书管理记录App实战项目,核心聚焦于"添加目标"功能的实现。作为一款跨平台应用,它需要同时兼顾Flutter框架的灵活性和OpenHarmony系统的特性。在实际开发中,目标管理功能是阅读…

📰

PyTorch到TensorRT编译原理深度解析:从IR转换到引擎生成的全流程

1. 这不是一次简单的“编译”,而是一场5393个文件参与的PyTorch到TensorRT工程化穿越你点开这个标题,大概率不是为了看一篇泛泛而谈的“TensorRT加速教程”。你真正想搞清楚的是:当一个工业级推理优化框架(TensorRT)试…

📰

Agent技能治理:TypeScript契约驱动的Nx单体工程实践

1. “agent-skills”不是库名,而是工程级能力抽象层的设计原点你第一次在 GitHub 或 Nx 工作区里看到agent-skills这个包名时,大概率会下意识认为:这是个封装了“AI Agent 常用工具函数”的 npm 包——比如调用天气 API、查维基百科、执行 sh…

📰

Transformer底层原理与工程避坑指南:从MultiheadAttention到Bert预训练暗面

1. 这不是“又一篇Transformer科普”,而是我三年里重写七次模型结构图后画出的血泪路线图你点开这篇,大概率正被三件事同时折磨:面试官突然问“Bert的[CLS] token为什么能代表整句语义”,组里新来的实习生把nn.MultiheadAttention…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬