基于图莫斯的CAN UDS升级上位机-LabVIEW版本(四):TOOMOSS_SID27_SecurityAccess.vi — 安全访问

1. 引言

在UDS刷写流程中,安全访问(0x27 Service) 是最关键的一道防线。它的作用是防止未经授权的操作------在刷写固件之前,ECU会要求上位机证明自己拥有合法的访问权限。这个验证过程通常基于 种子-密钥(Seed-Key) 机制:

  1. 上位机请求种子 :发送 27 01 请求,ECU返回一个随机数(种子)

  2. 上位机计算密钥:将种子输入到车厂提供的专用DLL中,计算出对应的密钥

  3. 上位机发送密钥 :发送 27 02 + 密钥,ECU验证通过后开放刷写权限

TOOMOSS_SID27_SecurityAccess.vi 就是负责完成这个完整流程的子VI。它调用通信基座发送请求和接收响应,并通过调用外部安全访问DLL(通常由车厂提供)完成种子到密钥的转换。


2. 子VI功能概述

2.1 设计目标

  • 发送 27 09 请求种子,接收ECU返回的种子数据

  • 调用外部安全访问DLL,将种子转换为密钥

  • 发送 27 0A + 密钥,接收ECU的验证结果

  • 返回最终执行状态

2.2 UDS 0x27服务协议说明

请求种子(27 09)

复制代码
请求:Byte 0: SID = 0x27, Byte 1: subFunction = 0x9
响应(肯定):Byte 0: SID = 0x67, Byte 1: subFunction = 0x09, Byte 2~N: 种子数据

发送密钥(27 0A)

复制代码
请求:Byte 0: SID = 0x27, Byte 1: subFunction = 0x0A, Byte 2~N: 密钥数据
响应(肯定):Byte 0: SID = 0x67, Byte 1: subFunction = 0x0A

否定响应(两种请求共用)

复制代码
Byte 0: SID = 0x7F, Byte 1: 0x27, Byte 2: NRC

2.3 输入参数

控件 类型 说明
设备句柄 U32 TOOMOSS_OpenDev(CAN).vi返回的设备句柄
通道号 枚举(CAN1/CAN2) 选择使用CAN1还是CAN2通道
物理地址 U32 请求报文ID(发送给ECU的CAN ID)
响应地址 U32 期望的响应报文ID(ECU回复的CAN ID)
安全访问DLL库路径 字符串 车厂提供的安全访问DLL的完整路径

2.4 输出参数

控件 类型 说明
响应数据 U8数组 完整的安全访问响应数据(包含27 02的响应)
返回值 I32 0表示成功,-1表示失败
错误信息 字符串 失败时的错误描述

3. 前面板设计


4. 程序框图设计

4.1 整体流程

复制代码
步骤1: 发送27 01请求种子 → 调用TOOMOSS_SendAndWaitResp.vi
                                    ↓
                    判断响应是否成功
                        ↓ 成功
步骤2: 从响应数据中提取种子
                        ↓
步骤3: 调用GenerateKeyExByDLL.vi → 获取密钥
                        ↓
步骤4: 发送27 02 + 密钥 → 调用TOOMOSS_SendAndWaitResp.vi
                                    ↓
                        判断响应 → 返回最终结果

4.2 第一步:请求种子(27 09)

构造请求数据 [0x27, 0x09],调用通信基座发送:

通信基座参数
设备句柄 子VI输入
通道号 子VI输入
物理地址 子VI输入
响应地址 子VI输入
请求数据 [0x27, 0x09]
数据长度 2
超时时间 500ms

判断响应

  • 若返回值 ≤ 0 → 请求种子失败,返回 -1

  • 若响应首字节 == 0x7F → 收到否定响应,解析NRC,返回 -1

  • 若响应首字节 == 0x67 → 肯定响应,进入下一步

4.3 第二步:提取种子数据

从27 09的肯定响应中提取种子:

响应格式[0x67, 0x09, seed0, seed1, seed2, ...]

  • 种子起始位置:索引2

  • 种子长度:响应长度 - 2(减去SID和子功能)

  • 使用 数组子集 函数从索引2开始提取

4.4 第三步:调用密钥生成DLL

将上一步提取的种子数据传递给 GenerateKeyExByDLL.vi

输入参数 来源
安全访问DLL库路径 子VI输入
种子数据 从27 09响应中提取的种子数组
种子长度 种子数组的实际长度

输出

  • 密钥数据(U8数组)

  • 密钥长度(I32)

  • 返回值(0表示成功,非0表示失败)

错误处理

  • 若GenerateKeyExByDLL.vi返回非0 → 密钥计算失败,返回-1

4.5 第四步:发送密钥(27 0A)

将SID(0x27)、子功能(0x0A)和密钥数据拼接为完整请求:

请求数据构造

复制代码
[0x27, 0x0A] + 密钥数据

使用 创建数组连接数组 函数将这三部分合并。

调用通信基座发送:

通信基座参数
设备句柄 子VI输入
通道号 子VI输入
物理地址 子VI输入
响应地址 子VI输入
请求数据 [0x27, 0x0A, 密钥字节...]
数据长度 2 + 密钥长度
超时时间 500ms

判断响应

  • 若返回值 ≤ 0 → 发送密钥失败,返回 -1

  • 若响应首字节 == 0x7F → 收到否定响应,解析NRC,返回 -1

  • 若响应首字节 == 0x67 → 安全访问成功,返回 0

4.6 常见NRC错误信息映射

NRC 含义 错误信息
0x12 子功能不支持 "该ECU不支持安全访问服务"
0x22 条件不满足 "当前会话不支持安全访问"
0x33 安全访问被拒绝 "安全访问被拒绝,请检查密钥是否正确"
0x35 无效密钥 "密钥不匹配,请检查密钥生成算法"
0x36 超出尝试次数 "解锁尝试次数已达上限"
0x37 时间延迟未到 "需要等待一段时间后才能再次尝试"
其他 未知 "安全访问失败,NRC=0x%02X"

5. GenerateKeyExByDLL.vi 接口设计

5.1 子VI功能说明

GenerateKeyExByDLL.vi 是一个封装子VI,它动态调用车厂提供的安全访问DLL,将输入的种子数据转换为密钥数据。该DLL的函数原型通常是:

c

复制代码
typedef int (*pGenerateKeyEx)(const unsigned char *iSeedArray,
                              unsigned short iSeedArraySize,
                              const unsigned int iSecurityLevel,
                              const char *iVariant,
                              unsigned char *ioKeyArray,
                              unsigned int iKeyArraySize,
                              unsigned int &oSize);

5.2 输入参数

控件 类型 说明
DLL库路径 字符串 安全访问DLL的完整路径
种子数据 U8数组 从ECU接收的种子
种子长度 U16 种子数据的字节数
安全等级 U32 通常为1,表示安全访问Level 1(可扩展)
变体名称 字符串 空字符串或特定变体标识
密钥缓冲区大小 U32 密钥数组的最大长度(建议16)

5.3 输出参数

控件 类型 说明
密钥数据 U8数组 计算出的密钥
密钥长度 U32 密钥的实际字节数
返回值 I32 0表示成功,非0表示失败

6. 典型调用示例

6.1 成功的安全访问流程

步骤 方向 数据 说明
1 Tx 27 01 请求种子
2 Rx 67 01 12 34 56 78 返回种子 12 34 56 78
3 --- --- DLL计算密钥(假设结果为 A1 B2 C3 D4)
4 Tx 27 02 A1 B2 C3 D4 发送密钥
5 Rx 67 02 验证通过,安全访问成功

6.2 密钥错误导致失败

步骤 方向 数据 说明
1 Tx 27 01 请求种子
2 Rx 67 01 12 34 56 78 返回种子
3 --- --- DLL计算密钥(但算法错误或版本不匹配)
4 Tx 27 02 XX YY ZZ WW 发送错误密钥
5 Rx 7F 27 35 NRC=0x35,密钥无效

7. 错误处理

错误场景 返回值 错误信息
设备句柄无效 -1 "设备句柄无效,请检查设备是否已打开"
请求种子超时 -1 "请求种子超时,ECU未响应"
请求种子否定响应 -1 根据NRC返回对应错误信息
GenerateKeyExByDLL返回非0 -1 "密钥计算失败,请检查DLL库是否正确"
发送密钥超时 -1 "发送密钥超时,ECU未响应"
发送密钥否定响应 -1 根据NRC返回对应错误信息

8. 注意事项

要点 说明
DLL路径 安全访问DLL通常由车厂或算法提供商提供,且路径中不应包含中文或特殊字符
种子长度 不同ECU的种子长度不同(常见4字节、6字节或8字节),子VI应自动适应
密钥长度 密钥长度通常与种子长度相同,但也可能不同,需根据实际DLL输出确定
尝试次数 部分ECU限制了安全访问的尝试次数(通常5次),超过后需等待或复位ECU
会话切换 安全访问通常需要在扩展会话(0x03)下执行,若收到NRC=0x7E,请先切换会话
超时时间 部分ECU的种子生成和密钥验证需要额外计算时间,建议超时设为1000ms以上
安全等级 本子VI默认使用Level 1(请求种子/发送密钥),部分ECU可能需要Level 2以上的安全访问(如27 05/27 06),可根据需要扩展

9. 总结

TOOMOSS_SID27_SecurityAccess.vi 是UDS刷写流程中最复杂的诊断服务之一。它涉及两个步骤的请求-响应交互,并且需要依赖外部安全访问DLL完成种子到密钥的转换。

本子VI的设计将种子请求、密钥计算和密钥发送三个环节串联为完整流程,调用者只需传入设备信息和安全访问DLL路径即可完成安全访问验证,无需关心内部协议细节。

在实际项目中,由于不同ECU的种子长度、密钥长度和安全访问算法各不相同,该子VI应设计为高度可配置的通用模块,以适应不同项目的需求。

下一篇将介绍 TOOMOSS_SID34-36-37_DownloadFlow.vi --- 下载流程,敬请期待。

相关推荐
马不啼1 小时前
NI HIL自动化测试10-Labview04-树形结构
labview·simulink·hil·veristand·teststand
其实防守也摸鱼4 小时前
KMP全栈开发:从Android到AI Agent的技术演进与实践
android·运维·网络·人工智能·学习·安全·macos
●VON7 小时前
鸿蒙 PC Markdown 编辑器内核:在 ArkWeb 中离线运行 CodeMirror 6
安全·华为·编辑器·harmonyos·鸿蒙
zzq779714 小时前
加固包闪退四象限定位:targetSdk 与保护策略实战解析
android·安全·安卓·安全架构
Promise微笑14 小时前
智能激光清障仪选型指南:高效运维与安全保障的关键考量
运维·安全
●VON15 小时前
鸿蒙 PC Markdown 编辑器存储安全:AtomicFile 原子提交与故障注入
安全·华为·编辑器·harmonyos·鸿蒙
网络研究院17 小时前
2026年上半年十大网络攻击和数据泄露事件
网络·安全·漏洞·风险·数据·泄露·事件
BEOL贝尔科技18 小时前
还在担心样本的安全吗?如何制定有效的温湿度异常应急预案?
人工智能·安全
未来之窗软件服务19 小时前
基于设备ID固化的SaaS客户端访问安全防护的必要性探析—东方仙盟
安全·仙盟创梦ide·东方仙盟·计算机考试