【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑤】
ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase05
作者:车端域控测试工程师
更新日期:2025年02月17日
关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023
TC11-005测试用例
用例ID | 测试场景 | 验证要点 | 参考条款 | 预期结果 |
---|---|---|---|---|
TC11-005 | 未授权访问复位服务 | 安全锁定时发送复位请求 | §7.3.4 | 返回NRC=0x33(安全访问拒绝) |
以下是对TC11-005测试用例的通俗化解释,采用生活场景类比和结构化说明:
通俗版测试流程说明
(就像手机输错密码被锁)
一、测试目的
验证当ECU的"安全锁"开启时(就像手机输错密码被锁),如果有人强行发送"重启设备"指令,系统会拒绝并提示"需要解锁"(对应错误码0x33)
二、通俗版测试步骤分解
阶段1:故意"输错密码"触发锁定
-
索要密码本
- 发送请求:“请给我密码本”(0x27服务)
- ECU回应:给出4位随机数密码本(如:12 34 56 78)
-
连续输错3次
- 第1次错:回复"密码错误"(0x35错误码)
- 第2次错:再报错
- 第3次错:系统警告"错误次数过多"(0x36错误码)
-
启动10分钟锁定期
- 类似手机输错密码后显示"请10分钟后再试"
阶段2:尝试"非法重启"验证锁定
-
发送重启指令
- 请求:“立刻重启设备”(0x11服务)
-
检查系统反应
- 预期回应:“拒绝操作,需要先解锁”(0x33错误码)
三、关键技术点生活化解释
技术术语 | 生活比喻 | 测试关注点 |
---|---|---|
安全访问服务 | 手机密码验证 | 错误次数统计是否准确 |
安全锁定状态 | 手机禁用功能 | 锁定期是否禁止关键操作 |
NRC 0x33 | "请先解锁"提示 | 错误提示是否正确 |
种子值 | 动态验证码 | 每次请求是否生成新密码本 |
四、为什么这样设计?
-
防暴力破解
- 就像ATM机吞卡机制,防止无限次尝试密码
-
关键操作保护
- 锁定期间禁止敏感操作(如刷机、重置)
-
错误追溯
- 系统会记录异常访问日志(类似手机的安全日志)
五、实际应用场景
当你的爱车在4S店维修时:
- 技师用诊断仪连接车载电脑
- 若未通过厂家授权验证
- 尝试执行复位ECU等敏感操作时
- 系统会拒绝并提示需要安全认证
六、测试结果判断标准
-
合格标准
- 3次错误尝试后必定锁定
- 锁定期内100%拒绝重启
- 提示明确的安全错误码
-
危险情况
- 未锁定状态下允许任意重启 → 安全漏洞
- 锁定后仍可执行操作 → 严重缺陷
七、扩展联想测试
可类比测试其他"锁定状态"下的禁止操作:
- 禁止软件更新
- 禁止删除故障码
- 禁止修改配置参数
通过这种"锁定-验证"机制,确保车辆在未授权状态下不会被非法操控,就像你的手机在锁定状态下无法被他人使用一样。
以下是为TC11-005设计的工业级CAPL测试用例,包含完整的安全锁定触发流程:
/*----------------------------------------------------------
Title:TC11-005 安全锁定时复位服务验证
作者:车端域控测试工程师
日期:2025-02-17
------------------------------------------------------------*/
variables {
// 通信参数
const long ReqID = 0x732; // 诊断请求标识符
const long ResID = 0x733; // 诊断响应标识符
const byte SecurityLevel = 0x01; // 安全等级1(根据OEM规范)
// 安全参数
const int MaxAttempts = 3; // 最大错误尝试次数
const dword LockTime = 600000; // 锁定时间10分钟(单位:ms)
byte seed[4]; // 安全种子存储
msTimer lockTimer; // 锁定状态计时器
}
testcase TC11_005_SecurityLockTest()
{
TestModuleTitle("TC11-005 安全锁定状态服务拒绝验证");
// ███ 阶段1:触发安全锁定 ███
testStep("STEP1 触发安全锁定机制");
// ▶ 1.1 请求安全种子
DiagRequestSeed:
message ReqID [CAN] {
dlc = 2;
byte(0) = 0x27; // 安全访问服务
byte(1) = SecurityLevel | 0x01; // 种子请求子功能
}
output(this);
// ▶ 1.2 接收种子
if(TestWaitForMessage(ResID, 200) && this.byte(0) == 0x67) {
seed[0] = this.byte(2); // 提取种子值
seed[1] = this.byte(3);
seed[2] = this.byte(4);
seed[3] = this.byte(5);
testStepPass("收到安全种子: %02X%02X%02X%02X",
seed[0], seed[1], seed[2], seed[3]);
} else {
testStepFail("种子请求失败");
return;
}
// ▶ 1.3 发送错误密钥(模拟攻击)
for(int i=1; i<=MaxAttempts+1; i++)
{
testStep("错误密钥尝试 %d/%d", i, MaxAttempts);
// 生成错误密钥(示例算法)
byte invalidKey[4];
invalidKey[0] = ~seed[0] + i; // 实际需用OEM算法
invalidKey[1] = seed[1] ^ 0x55;
invalidKey[2] = seed[2] | 0xAA;
invalidKey[3] = seed[3] - 0x10;
// 发送密钥
message ReqID [CAN] {
dlc = 6;
byte(0) = 0x27;
byte(1) = SecurityLevel | 0x02; // 密钥发送子功能
byte(2) = invalidKey[0];
byte(3) = invalidKey[1];
byte(4) = invalidKey[2];
byte(5) = invalidKey[3];
}
output(this);
// 响应处理
if(TestWaitForMessage(ResID, 200)) {
if(this.byte(0) == 0x7F) {
switch(this.byte(2)) {
case 0x35: // 无效密钥
testAddLog("尝试%d返回NRC=0x35", i);
break;
case 0x36: // 超过尝试次数
testStepPass("安全锁定已触发");
setTimer(lockTimer, LockTime); // 启动锁定计时
break;
}
}
}
}
// ███ 阶段2:验证服务拒绝 ███
testStep("STEP2 验证复位服务拒绝");
// ▶ 2.1 发送复位请求
message ReqID [CAN] {
dlc = 2;
byte(0) = 0x11; // ECU复位服务
byte(1) = 0x01; // 硬件复位子功能
}
output(this);
// ▶ 2.2 响应验证
if(TestWaitForMessage(ResID, 300)) {
if(this.byte(0) == 0x7F &&
this.byte(1) == 0x11 &&
this.byte(2) == 0x33) {
testStepPass("成功收到NRC=0x33");
testCasePass("测试通过");
} else {
testStepFail("收到异常响应: %02X %02X %02X",
this.byte(0), this.byte(1), this.byte(2));
}
} else {
testStepFail("响应超时");
}
}
/*----------------------------------------------------------
安全状态监控模块(示例)
----------------------------------------------------------*/
on sysvar Security::LockStatus {
if(@this::LockStatus == 1) {
testAddLog("安全锁定激活,剩余时间:%.1f分钟",
(LockTime - getTimer(lockTimer))/60000.0);
}
}
流程图解(新手友好版)
关键参数说明表
参数名称 | 示例值 | 实际应用要点 |
---|---|---|
SecurityLevel | 0x01 | 需与OEM定义的访问层级一致 |
MaxAttempts | 3 | 根据ISO 14229-1建议值设置 |
LockTime | 600000 ms | 典型值为5-30分钟(OEM指定) |
错误密钥算法 | 位运算组合 | 实际需使用OEM的正向算法生成错误值 |
响应超时 | 300 ms | 需大于ECU响应时间2倍以上 |
执行结果判定矩阵
检查项 | 通过标准 | 失败处理措施 |
---|---|---|
安全种子请求 | 100%成功获取4字节种子 | 检查物理层通信 |
错误密钥响应 | 前3次返回NRC=0x35 | 验证安全计数器逻辑 |
第4次尝试响应 | 必须返回NRC=0x36 | 检查锁定触发条件 |
锁定期间复位请求 | 100%返回NRC=0x33 | 检查安全状态机 |
锁定时间精度 | 误差≤±5% | 校准ECU内部计时器 |
工程实践建议
-
密钥算法集成
实际项目中使用CAPL DLL
调用OEM提供的加密算法:#pragma library("SecurityAlgorithm.dll") void GenerateKey(byte seed[], byte key[]);
-
多场景验证
// 可扩展测试场景: // 1. 不同安全等级的锁定 // 2. 锁定期间其他服务访问 // 3. 锁定超时自动恢复
-
诊断监控配置
在CANoe Diagnostic Console中设置:[Security] AccessTiming = Fast DelayBetweenAttempts = 2000ms
-
自动化集成
使用Test Module将用例集成到自动化序列:testcase ExecuteAllSecurityTests() { TC11_005_SecurityLockTest(); TC11_006_KeyRecoveryTest(); // 更多安全测试用例... }
提示:在
Write
窗口添加过滤器快速定位关键报文:
id==733h && (byte(0)==7Fh || byte(0)==67h)