如何对ARXML中的SECURED-I-PDUs进行解密?
处理SECURED-I-PDUs解密的核心步骤(C++实现)
1. 建立节点关联映射
你已解析的两个节点需要先完成关联绑定:
- SECURE-COMMUNICATION-PROPS-SET:存储加密/解密核心参数,如算法类型、密钥索引、校验方式、标签长度等
- ND-TO-END-PROTECTIONS:定义受保护的I-PDU列表,以及每个I-PDU对应的保护配置引用
在C++中可以这么实现:
- 遍历
ND-TO-END-PROTECTIONS下的PROTECTED-I-PDU条目,通过SECURE-COMMUNICATION-PROPS-REF属性,匹配到对应的SECURE-COMMUNICATION-PROPS-SET实例 - 用哈希表(如
std::unordered_map<std::string, SecureCommProps>)存储映射关系,Key为I-PDU名称,Value为封装好的参数结构体
示例参数结构体:
struct SecureCommProps { std::string cipherAlgorithm; // 加密算法,如AES-128-CBC std::string authAlgorithm; // 校验算法,如HMAC-SHA256 uint32_t keyIndex; // 密钥索引,关联车载密钥管理系统中的密钥 bool enableEncryption; // 是否启用加密 bool enableAuthentication; // 是否启用完整性校验 uint8_t authTagLength; // 校验标签长度(单位:字节) };
2. 拆分PDU结构
SECURED-I-PDU通常由保护元数据和加密载荷两部分组成:
- 元数据包含密钥索引、防重放计数器、校验标签等,格式由
SECURE-COMMUNICATION-PROPS-SET中的PROTECTION-FORMAT字段定义 - 先从ARXML或总线数据中拆分这两部分,验证元数据合法性(如密钥索引是否匹配映射项、计数器是否递增)
3. 执行解密与校验流程
步骤A:获取对应密钥
通过keyIndex从车载密钥存储模块(或自定义密钥管理组件)获取对称密钥,注意密钥长度必须匹配算法要求(如AES-128对应16字节密钥)
步骤B:解密载荷(若启用加密)
以AES-CBC算法为例,用OpenSSL库实现的C++代码片段:
#include <openssl/aes.h> bool decryptAES(const uint8_t* encryptedData, size_t dataLen, const uint8_t* key, const uint8_t* iv, uint8_t* decryptedData) { AES_KEY aesKey; if (AES_set_decrypt_key(key, 128, &aesKey) != 0) { return false; } AES_cbc_encrypt(encryptedData, decryptedData, dataLen, &aesKey, iv, AES_DECRYPT); return true; }
步骤C:完整性校验(若启用校验)
以HMAC-SHA256为例,用OpenSSL库实现的校验代码片段:
#include <openssl/hmac.h> bool verifyHMAC(const uint8_t* data, size_t dataLen, const uint8_t* key, size_t keyLen, const uint8_t* expectedTag, size_t tagLen) { uint8_t computedTag[EVP_MAX_MD_SIZE]; unsigned int computedTagLen; HMAC(EVP_sha256(), key, keyLen, data, dataLen, computedTag, &computedTagLen); return (computedTagLen == tagLen && memcmp(computedTag, expectedTag, tagLen) == 0); }
4. 异常处理
- 若密钥索引无效、计数器不递增、校验标签不匹配,直接丢弃该PDU,或按车载系统规范上报错误
- 部分厂商会对保护格式做自定义扩展,需结合厂商ARXML扩展规范调整解析逻辑
内容的提问来源于stack exchange,提问作者Steffen Roeber
相关产品推荐
相关产品推荐

