尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

UDS 0x27安全访问服务测试用例设计:从需求拆解到SeedKey验证

UDS 0x27安全访问服务测试用例设计:从需求拆解到SeedKey验证 做车载网络诊断的测试工程师几乎都绕不开 0x27 服务。它叫安全访问SecurityAccess是 UDS 诊断协议里最考验用例设计能力的一个服务——因为 0x27 不像 0x22 读数据那样只是查表也不像 0x2E 写数据那样直接落盘它牵扯到 Seed 生成、Key 校验、尝试次数、延时锁止、会话状态、安全等级映射这些东西任何一个环节设计不到位测试用例就会漏掉真实故障。这篇内容围绕“网络诊断 04 - 0x27 服务根据需求设计用例”展开重点解决三个问题需求文档里关于 0x27 的描述应该怎么拆解拆解出来的需求点如何映射成可执行的测试用例以及实际执行时如何验证 SeedKey 流程、否定响应码NRC、锁止时间和会话切换这些细节。同时会把车载以太网诊断中常见的 DNS 解析问题纳入用例设计范围因为在实际网络诊断场景里0x27 请求能不能到达 ECU往往先取决于网络层是否通了。本文适合诊断协议测试工程师、ECU 集成测试人员、以及刚接触 UDS 测试的嵌入式工程师阅读。看完能直接用里面的用例模板和检查清单不需要再从零搭一套方法。1. 0x27 服务用例设计范围速览设计项说明服务名称安全访问服务SecurityAccess服务 ID请求 0x27正响应 0x67否定响应 0x7F 27 NRC核心流程请求 Seed - 计算 Key - 发送 Key - ECU 校验并解锁典型子功能0x01/0x02安全等级 10x03/0x04安全等级 20x05/0x06 等按需求定义常见否定响应码0x12、0x13、0x22、0x24、0x31、0x33、0x35、0x36、0x37用例设计重点Seed 长度、Key 算法、尝试次数、延时锁止、会话切换、安全等级权限网络诊断扩展DoIP 诊断连接、DNS 解析、路由激活、连接超时对 0x27 请求的影响测试环境诊断仪、ECU 测试台架、CANoe/CANalyzer、总线日志工具适合场景台架功能测试、网络诊断集成测试、生产线 EOL 解锁流程验证2. 为什么 0x27 用例设计容易漏很多测试团队设计 0x27 用例时只写了“发送 0x27 01 获取 Seed发送 0x27 02 发送 Key验证解锁成功”这一条主路径。然后自动化脚本一跑全链路通过就认为覆盖完成。这其实只覆盖了需求文档里 10% 的内容。0x27 服务真正容易漏的地方在下面几个方向需求里如果有“安全等级 1 可以执行读写安全等级 2 才能执行刷写”用例设计要验证跨等级访问是否被拒绝。只测解锁成功不测越权等于没测。ECU 对 Seed 的随机性、长度、数据排列有要求用例需要验证连续多次请求 Seed 时返回内容是否符合需求。有的 ECU 在固定周期内返回相同 Seed有的要求每次随机这两种行为对应的断言完全不同。Key 错误次数达到上限后进入锁定状态需求一般会写明锁定时长。用例设计要确认锁定期间即使 Key 正确也不能解锁锁定时间结束后是否自动恢复。延时条件不满足时ECU 应返回 0x37。这个场景经常被忽略因为测试人员在解锁成功后短时间再次请求 Seed理论上不该收到 0x37但如果需求规定“距上次解锁小于 N 秒不允许重新请求”就必须按需求设计用例。0x27 服务对会话模式敏感。很多 ECU 只在扩展会话0x03下允许请求 Seed默认会话下直接返回 0x7F 27 0x22。用例设计时要把会话切换作为前置条件明确写出来。设计 0x27 用例时要有一个意识需求文档里每一句话都至少要对应一个“正向通过”和一个“反向拒绝”的测试用例。如果需求写“Key 校验错误不超过 3 次”那么用例至少要有第 1 次错误、第 2 次错误、第 3 次错误锁定、锁定后正确 Key 解锁失败、解锁时间结束后 Key 解锁成功这些分支。这还不包括报文长度异常、子功能不支持、Seed 请求时序错误等协议层面的用例。3. 适用场景与使用边界0x27 服务用例设计主要用在三类场景第一类是 ECU 台架功能测试。通过 CANoe 或诊断仪连接 ECU验证安全访问流程是否符合需求。这是最常用的场景用例可以在 HIL 台架上自动回归。第二类是网络诊断集成测试。在车载以太网环境下诊断仪通过 DoIP 连接 ECU此时 0x27 报文走 TCP/UDP 传输。测试不仅要关注 0x27 服务本身还要关注网络层对诊断请求的影响。比如 DNS 解析失败时诊断连接根本无法建立更谈不上安全访问。这就是“网络诊断显示 DNS”这类问题经常和 0x27 测试同时出现的原因。第三类是产线 EOL 解锁流程验证。生产线刷写、标定之前需要做安全访问解锁用例设计要验证解锁成功率和失败后的恢复流程。产线场景对时间的敏感性高延时锁止用例要特别设计边界值避免产线被锁死造成停线。使用边界方面要明确一点0x27 是安全访问机制测试用例设计必须基于授权和合规前提。SeedKey 算法通常是供应商保密的测试人员不应当逆向或公开真实算法。实际用例中可以使用模拟算法或测试桩不能把真实的解锁算法写入公开测试文档。涉及整车、ECU、零部件的数据和算法都要遵守保密协议和合规要求。4. 测试环境与前置条件0x27 服务测试在动手写用例之前需要先确认环境满足以下条件。4.1 硬件与工具链ECU 测试台架或实车 ECU确认供电和总线连接正常。总线接口设备比如 CANoe、CANalyzer、PCAN、VN1630 等具体看团队现有工具链。诊断仪或自动化测试软件常用的是 CANoe 的 Diagnostic 模块、vTestStudio、Pytest 加 python-can 的组合。如果走网络诊断需要准备车载以太网接口和 DoIP 连接环境。4.2 需求文档信息用例设计前必须从需求文档中提炼出以下字段提取不出来就要找需求工程师确认0x27 支持的子功能列表和安全等级映射。Seed 长度和 Seed 随机性要求。Key 算法来源是供应商库还是本地模拟。错误 Key 的最大尝试次数。锁定时间长度。解锁有效持续时间。允许执行 0x27 的会话模式。解锁后允许执行的服务范围。4.3 环境检查方法执行用例前建议用下面的方式确认环境可用。# 检查总线和接口状态以 CANoe 环境为例命令按实际工具调整 cansend vcan0 02 10 03如果使用 python-can 做快速验证import can bus can.interface.Bus(channelvcan0, interfacesocketcan) msg can.Message(arbitration_id0x7E0, data[0x02, 0x10, 0x03], is_extended_idFalse) bus.send(msg) response bus.recv(timeout1) print(response)5. 从需求到用例拆解方法0x27 用例设计最关键的一步是把需求条目拆成可验证的原子行为。拿一条典型需求举例需求原文“ECU 上电后处于默认会话此时不允许安全访问。诊断仪切换到扩展会话后请求 0x27 01 获取 SeedECU 返回 8 字节随机数诊断仪发送 0x27 02 上传 KeyKey 正确则解锁成功连续 3 次错误则锁定 10 秒锁定期间即使 Key 正确也返回 0x36。”这条需求可以拆成十个需求点需求点需求描述用例设计方向R1默认会话下不允许安全访问验证默认会话请求 Seed 返回 0x22R2扩展会话下才允许请求 Seed验证扩展会话请求 Seed 正常返回R3Seed 长度为 8 字节验证响应长度和数据格式R4Seed 为随机数连续多次请求验证不完全相同R5支持子功能 0x01/0x02验证正响应 0x67 01/02R6Key 正确则解锁成功验证解锁后允许执行受保护服务R7Key 错误返回 0x35验证错误 Key 的否定响应R8连续 3 次错误锁定确认第 3 次错误后状态变化R9锁定期间返回 0x36锁定期间发送正确 Key 也被拒绝R1010 秒后自动恢复解锁时间结束后可重新请求 Seed这一步把需求转换成用例设计的方向后面的工作就是为每个需求点补充前置条件和具体步骤。实际项目里需求文档很少写得这么清晰大概率是“0x27 安全访问按标准实现”这种模糊描述。遇到这种情况要主动把 UDS 标准里的默认行为补充进去并在用例中标注“待需求确认”不要直接默认某个行为是对的。6. 0x27 服务核心用例设计下面给出一个可以直接参考的 0x27 用例设计模板。用例编号建议按模块划分前置条件、测试步骤、预期结果必须写清楚。6.1 主流程用例用例编号TC_0x27_001测试目的验证 0x27 01 获取 Seed 和 0x27 02 发送 Key 的正常解锁流程前置条件ECU 处于扩展会话未锁定诊断仪已连接测试步骤1. 诊断仪发送 0x27 012. 接收 Seed3. 使用正确算法计算 Key4. 发送 0x27 02 Key5. 接收响应预期结果第一步返回 0x67 01 Seed第四步返回 0x67 02ECU 解锁成功判定标准响应中的服务 ID 为 0x67子功能与请求一一对应6.2 错误 Key 和锁定用例用例编号TC_0x27_007测试目的验证错误 Key 连续 3 次后锁定前置条件ECU 处于扩展会话未锁定测试步骤1. 请求 Seed2. 发送错误 Key如全部为 0x003. 重复 3 次4. 第 4 次发送正确 Key预期结果前 3 次返回 0x7F 27 0x35第 3 次后进入锁定状态第 4 次发送正确 Key 返回 0x7F 27 0x36判定标准是否连续计数、锁定后正确 Key 被拒绝6.3 子功能不支持用例用例编号TC_0x27_013测试目的验证不支持的子功能返回 0x12前置条件ECU 正常并处于扩展会话测试步骤1. 发送 0x27 0x7F或需求中不存在的子功能预期结果返回 0x7F 27 0x12判定标准NRC 为 0x12且响应时间在需求范围内6.4 报文长度异常用例用例编号TC_0x27_018测试目的验证 Seed 请求多余数据或 Key 长度不符时返回 0x13前置条件ECU 正常并处于扩展会话测试步骤1. 发送 0x27 01 额外数据2. 发送长度短于预期的 Key预期结果返回 0x7F 27 0x13判定标准NRC 为 0x13且不影响后续正常解锁6.5 会话切换与安全等级用例用例编号TC_0x27_025测试目的验证会话切换后解锁状态和权限范围前置条件ECU 已通过 0x27 01/02 解锁安全等级 1测试步骤1. 切换到默认会话2. 尝试执行受保护服务3. 切换回扩展会话预期结果默认会话下受保护服务被拒绝回到扩展会话后状态按需求重置判定标准解锁状态是否在指定会话切换动作后失效6.6 延时条件用例用例编号TC_0x27_031测试目的验证延时条件未满足时返回 0x37前置条件ECU 已解锁且需求规定解锁后 N 秒内不允许重新请求测试步骤1. 完成一次解锁2. 立即再次请求 0x27 01预期结果根据需求返回 0x37 或 0x24判定标准与需求中的延时策略一致6.7 默认会话访问控制用例用例编号TC_0x27_035测试目的验证默认会话下安全访问被拒绝前置条件ECU 上电后处于默认会话测试步骤1. 发送 0x27 01预期结果返回 0x7F 27 0x22判定标准NRC 为 0x22且 ECU 无状态变化7. 网络诊断中的 DNS 与 DoIP 联动用例“网络诊断显示 DNS”是常见网络诊断问题。在车载以太网环境下0x27 服务运行在 DoIP 之上诊断仪要先完成网络层连接才能发送诊断报文。DNS 解析失败会直接导致诊断连接建立不了此时根本走不到 0x27 无响应那一步。所以 0x27 用例设计不能只看诊断层还要增加网络层依赖用例。建议在用例设计中加入以下场景用例编号TC_NET_0x27_001测试目的验证 DNS 解析失败时 0x27 请求不可达前置条件车载以太网环境DoIP 连接建立前测试步骤1. 配置诊断仪使用错误 DNS 服务器2. 触发 DoIP 节点发现3. 观察诊断连接状态4. 尝试发送 0x27 01预期结果DoIP 连接建立失败0x27 请求无响应或超时判定标准诊断仪日志记录 DNS 解析失败网络层错误优先于诊断层错误用例编号TC_NET_0x27_002测试目的验证 DNS 恢复后 0x27 请求恢复前置条件上一条用例执行完成诊断为异常状态测试步骤1. 恢复 DNS 配置2. 重新建立 DoIP 连接3. 发送 0x27 01 和正确 Key预期结果诊断连接恢复安全访问流程正常判定标准0x27 请求在连接建立后可正常响应这类用例的价值在于它能把“网络诊断显示 DNS”和“0x27 安全访问”联动起来避免测试人员只盯着诊断层 NRC 排查问题。实际项目中0x27 超时很多时候不是 ECU 不响应而是网络层报文根本没到 ECU。DoIP 环境下 0x27 请求示例import socket import struct # 构造 DoIP 诊断报文示例实际项目需要按 DoIP 标准填充报文头 payload bytes([0x02, 0x27, 0x01]) # 长度 0x27 请求 Seed doip_header struct.pack(BHI, 0x04, 0x8001, len(payload)) with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(5) s.connect((192.168.0.10, 13400)) s.sendall(doip_header payload) response s.recv(1024) print(response.hex())这个例子只做通信验证用真实项目里的 DoIP 报文头需要严格按标准实现。测试重点是确认 0x27 报文能通过网络层完整到达 ECU并能收到正确响应。8. 测试执行与日志分析0x27 用例执行过程中日志分析比单纯看 PASS/FAIL 更重要。因为 0x27 的很多问题不是“服务没响应”而是“响应码不符合预期”或者“时序不对”。8.1 日志记录要点每次请求 Seed 的时间戳。Seed 原始数据和 Key 计算输入。每次响应的时间戳和 NRC。会话切换动作和对应时间。锁定发生时刻和恢复时刻。# 抓取总线日志以 CANoe 脚本编译和回放为例命令按实际环境调整 canoe.exe -project 0x27_test.cfg -run -report8.2 CAPL 脚本示例如果使用 CANoe可以通过 CAPL 脚本自动完成 0x27 的解锁流程。下面的脚本只做流程参考实际的 SeedKey 计算需要替换成安全算法库接口。// CAPL 示例0x27 解锁流程自动化 on start { byte requestSeed[2] {0x02, 0x27}; byte subFunc 0x01; byte seedData[8]; // 发送 0x27 01请求 Seed diagRequest SendSeed; SendSeed.SetP2(100); if (SendSeed.SendRequest()) { // 等待响应 } }这里的重点是自动化脚本里要记录每一次请求和响应并在失败时自动保存诊断报文。建议把 Seed 和 Key 的原始数据写入 CSV 文件便于回放。同时不要直接在脚本里硬编码真实 SeedKey 算法通过外部 DLL 或接口调用更安全。8.3 pytest 用例示例如果团队用 Python 做自动化可以参考下面的用例结构。用参数化方式覆盖不同子功能和不同 NRC。import pytest import can class TestSecurityAccess: def send_uds(self, bus, data): msg can.Message(arbitration_id0x7E0, datadata, is_extended_idFalse) bus.send(msg) return bus.recv(timeout1) pytest.mark.parametrize( sub_func, expected_response, [ (0x01, 0x67), # 请求 seed (0x03, 0x67), # 请求 high 等级 seed ], ) def test_request_seed(self, bus, sub_func, expected_response): response self.send_uds(bus, [0x02, 0x27, sub_func]) assert response.data[0] expected_response注意这里只是自动化框架示例实际项目需要根据 ECU 的 ID 和诊断实现调整。用例执行完成后要保留完整日志方便问题追溯。9. 资源占用与性能观察0x27 服务虽然不涉及图像或大模型推理但它的性能测试有独特价值。测试时要记录以下时间诊断仪发送 0x27 01 到收到 Seed 的时间间隔。ECU 发送 Key 到收到解锁确认的时间间隔。连续错误 Key 时的响应时间。锁定状态下的响应时间。解锁有效期内反复请求的行为。生产环境中0x27 解锁失败导致产线停线是常见问题。通过性能观察可以发现两种情况ECU 响应太慢导致诊断仪超时。比如 Seed 请求超过诊断仪 P2 时间直接被误判为无响应。ECU 响应太快但状态未就绪导致逻辑错误。比如收到 Seed 后立即发送 Key但 ECU 内部算法尚未完成。两种情况的处理方式完全不同。前者要调整诊断仪超时参数或优化 ECU 响应后者要在用例中增加延时边界模拟真实协议栈的时序差异。10. 常见问题与排查方法问题现象可能原因排查方式解决方案0x27 01 无响应诊断连接未建立或 DoIP 连接失败检查网络层日志、DNS 解析、TCP 连接状态先恢复网络连接再重新发送请求0x27 01 返回 0x7F 27 0x12子功能不支持检查需求文档中的子功能列表改用支持的子功能0x27 01 返回 0x7F 27 0x22会话条件不满足检查当前会话模式先切换到扩展会话0x27 02 返回 0x7F 27 0x35Key 计算错误检查 Seed 和算法参数核对算法和 Seed 长度0x27 02 返回 0x7F 27 0x36连续错误导致锁定查看锁定时间戳等待解锁时间结束0x27 02 返回 0x7F 27 0x37延时未到查看解锁历史记录按需求等待延时0x27 01 返回 0x7F 27 0x13报文长度错误检查请求报文长度去掉多余数据DNS 解析失败导致连接失败网络配置错误抓取 DoIP 连接日志修复 DNS 配置需要特别提醒的是锁定状态0x36的排查不能只看当前报文一定要看历史记录。因为 0x36 是状态性响应不是单次 Key 错误导致的。测试人员应该检查从第一次错误到当前时刻的时间线确认锁定计数是从哪一次开始的。11. 用例评审与覆盖率检查0x27 用例设计完成后建议用下面的检查清单做一次完整性评审。是否覆盖需求文档中所有 0x27 子功能是否覆盖所有 NRC包括 0x12、0x13、0x22、0x24、0x31、0x33、0x35、0x36、0x37。是否覆盖会话切换场景是否覆盖锁定状态、解锁恢复和延时策略是否覆盖 Seed 长度、随机性、重复请求行为是否覆盖错误 Key 的边界次数第 N-1 次和第 N 次是否考虑网络诊断环境下 DNS 和 DoIP 连接异常对 0x27 的影响是否考虑自动化脚本执行失败后的日志保存和恢复流程覆盖率检查最好用需求追踪矩阵来做。每个需求条目对应一个或多个用例编号反向检查时每个用例编号也必须能回溯到需求条目。如果某个用例没有对应的需求来源要主动标记为“补充验证项”而不是直接删除。12. 最佳实践与使用建议第一0x27 用例设计不要只停留在“能解锁成功”层面。要把 Seed 生成、Key 校验、锁止恢复串成完整链路每一条链路分支都要有对应的用例。第二测试数据要留痕。Seed 值、Key 值、请求时间、响应时间、NRC 全部记录到日志。后续问题排查时这些数据远比“用例通过”四个字有价值。第三网络诊断环境下先确认网络层再诊断 0x27。遇到 0x27 超时没响应先看 DNS、DoIP 连接、TCP 会话再分析 ECU 应用层。第四SeedKey 算法不要直接写在测试脚本里。使用加密库或外部算法模块避免核心算法泄露。测试文档中只描述测试方法和预期结果不要包含算法实现细节。第五保持用例的独立性。每个 0x27 用例执行前都应当把 ECU 恢复到已知初始状态否则前一个用例的锁定状态会影响后续用例结果。自动化执行时前置条件里要明确加入复位或会话重置步骤。第六涉及真实车辆、ECU、供应商算法时严格遵守授权和保密要求。0x27 安全访问的目的是保护 ECU 数据安全测试用例设计同样要服务于这个目标。13. 总结与下一步0x27 服务用例设计是所有 UDS 服务里最需要“需求拆解能力”的一项。它不复杂但分支多、状态多、时序敏感。这篇文章给的用例模板可以直接带入项目使用核心是把需求文档中的每一个约束条件拆成可验证的用例分支然后通过自动化脚本回归。建议第一次设计 0x27 用例时先按第 6 节的主流程、错误 Key、锁定、子功能不支持、报文长度异常、会话切换、默认会话拒绝这七类用例执行一遍。跑通后再补充延时条件、Seed 随机性和网络诊断联动用例。最容易踩的坑是只测主路径不测异常分支以及忽略网络层对诊断连接的影响。后续可以继续扩展的方向包括把 0x27 用例接入 CI 持续集成、增加模糊测试、在 HIL 台架上做全自动化回归、结合诊断描述文件自动生成部分用例。如果你手头有现成的 ECU 测试台架建议先拿 TC_0x27_001 和 TC_0x27_007 做一轮验证这两条用例跑通后0x27 的核心链路就基本受控了。
返回列表