3、密码学基础:对称加密(AES)、非对称加密(RSA、ECC)、哈希函数(SHA-256)、数字签名
各位同学,咱们今天聊点硬核的。密码学,说白了就是给车载数据加把锁。我做了这么多年车载安全,见过太多因为加密没做好导致的黑客攻击案例。嗯,咱们今天就把这四种核心工具讲透。
3.1 对称加密:AES
对称加密,顾名思义,加密和解密用的是同一把钥匙。就像你家大门钥匙,开门关门都用它。在车载网络里,AES(高级加密标准)是绝对的主流。
AES 的核心参数
| 密钥长度 | 轮数 | 典型应用场景 |
|---|---|---|
| AES-128 | 10轮 | CAN FD 报文加密 |
| AES-192 | 12轮 | 车载以太网通信 |
| AES-256 | 14轮 | 固件升级、密钥管理 |
我个人习惯在车载项目里用 AES-128 就够了。为什么?因为车载 ECU 算力有限,128 位密钥在安全性和性能之间平衡得最好。我曾经在一个项目中,客户非要上 AES-256,结果那个老款 MCU 跑加密任务时,CAN 报文直接丢帧了……后来乖乖换回 128。
实战代码:AES-128 CBC 模式加密
#include <mbedtls/aes.h>
mbedtls_aes_context aes_ctx;
unsigned char key[16] = {0x2b, 0x7e, 0x15, 0x16, ...};
unsigned char iv[16] = {0x00, 0x01, 0x02, ...};
unsigned char input[16] = "CAN_MSG_DATA";
unsigned char output[16];
mbedtls_aes_setkey_enc(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT,
16, iv, input, output);
避坑指南:我曾经在调试时发现,每次加密结果都不一样。查了半天,原来是 IV(初始化向量)每次都在变。记住:同一把密钥 + 同一个 IV = 同样的密文,这在车载通信里是致命的。IV 必须随机生成,且每次通信都要换。
3.2 非对称加密:RSA 与 ECC
非对称加密,说白了就是两把钥匙:公钥加密,私钥解密。你想想看,在车载场景里,ECU 之间要安全交换 AES 密钥,总不能明文传吧?这时候非对称加密就派上用场了。
RSA vs ECC 对比
| 特性 | RSA-2048 | ECC-256 |
|---|---|---|
| 密钥长度 | 2048 bit | 256 bit |
| 签名速度 | 慢 | 快 |
| 车载适用性 | 适合 OTA 签名 | 适合 V2X 通信 |
我个人更偏爱 ECC。为什么?因为 ECC 在同等安全强度下,密钥长度只有 RSA 的十分之一。我记得有一次做 V2X 项目,RSA 签名报文太大,导致通信延迟超标。换成 ECC-256 后,问题迎刃而解。
ECC 密钥生成示例(OpenSSL)
# 生成 ECC 私钥
openssl ecparam -genkey -name prime256v1 -out ecdsa_private.pem
# 提取公钥
openssl ec -in ecdsa_private.pem -pubout -out ecdsa_public.pem
# 查看密钥信息
openssl ec -in ecdsa_private.pem -text -noout
注意:RSA 的密钥生成速度极慢。我曾经在产线上遇到过,ECU 第一次上电要生成 RSA 密钥对,结果等了 30 秒……产线工人直接投诉了。所以,车载场景下,密钥对最好预置,不要在运行时生成。
3.3 哈希函数:SHA-256
哈希函数,说白了就是「数据指纹」。不管你的数据是 1KB 还是 1GB,SHA-256 都会给你一个 256 位的固定长度摘要。而且,哪怕只改一个比特,摘要结果就完全不一样。
SHA-256 在车载中的典型用途
- 固件完整性校验:刷写前计算哈希,确保固件没被篡改
- 密码存储:绝不存明文密码,只存哈希值
- 数字签名的基础:先哈希,再签名
我的经验:SHA-256 在大多数 MCU 上都有硬件加速模块。如果你发现软件算哈希太慢,记得查一下芯片手册,开启硬件 SHA 引擎。我曾经在一个项目中,软件算 SHA-256 花了 200ms,开启硬件加速后直接降到 5ms。
// 使用 mbedTLS 计算 SHA-256
#include <mbedtls/sha256.h>
mbedtls_sha256_context ctx;
unsigned char hash[32];
unsigned char data[] = "Firmware_Version_1.2.3";
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts(&ctx, 0); // 0 表示 SHA-256
mbedtls_sha256_update(&ctx, data, strlen(data));
mbedtls_sha256_finish(&ctx, hash);
mbedtls_sha256_free(&ctx);
// 此时 hash 数组里就是 32 字节的摘要
3.4 数字签名:让数据「不可抵赖」
数字签名,说白了就是「电子印章」。它结合了哈希函数和非对称加密:先对数据算哈希,然后用私钥加密这个哈希。接收方用公钥解密,再自己算一遍哈希,对比一下就知道数据有没有被篡改。
车载场景下的签名流程
- 发送方:数据 → SHA-256 → 摘要 → 私钥加密 → 签名
- 接收方:数据 → SHA-256 → 摘要1
- 接收方:签名 → 公钥解密 → 摘要2
- 对比摘要1和摘要2,一致则通过
ECDSA 签名示例(mbedTLS)
mbedtls_ecdsa_context ecdsa;
mbedtls_ecdsa_init(&ecdsa);
// 加载私钥(假设已从 PEM 文件读取)
mbedtls_pk_context pk;
mbedtls_pk_parse_key(&pk, private_key_pem, key_len, NULL, 0);
mbedtls_ecdsa_from_keypair(&ecdsa, mbedtls_pk_ec(pk));
// 对哈希签名
unsigned char hash[32]; // 假设已计算好
unsigned char sig[64];
size_t sig_len;
mbedtls_ecdsa_write_signature(&ecdsa, MBEDTLS_MD_SHA256,
hash, 32, sig, &sig_len, NULL, NULL);
// 验证签名
mbedtls_ecdsa_read_signature(&ecdsa, hash, 32, sig, sig_len);
我曾经踩过的坑:数字签名验证时,一定要检查返回值。有一次我写代码时忘了检查 mbedtls_ecdsa_read_signature 的返回值,结果签名验证失败也没报错,ECU 直接执行了被篡改的固件……从那以后,我每条签名验证代码后面都加了断言。
3.5 四种技术的协同工作
在实际车载项目中,这四种技术很少单独使用。我给大家画个典型场景:
- ECU 刷写:先用 RSA/ECC 签名固件,ECU 用公钥验证签名(数字签名),再用 SHA-256 校验完整性
- 安全通信:先用 ECC 交换 AES 密钥(非对称加密),然后用 AES 加密实际数据(对称加密)
- 诊断会话:用 SHA-256 对诊断请求生成挑战码,用 AES 加密响应
说白了,非对称加密负责「密钥分发」,对称加密负责「数据加密」,哈希函数负责「完整性校验」,数字签名负责「身份认证」。四者缺一不可。
我的建议:刚开始做车载安全时,别想着自己实现加密算法。用 mbedTLS、OpenSSL 这些成熟库就好。我曾经见过有人自己写 AES 实现,结果 CBC 模式写错了,加密出来的数据解密后全是乱码……嗯,专业的事交给专业的库。
好了,密码学基础就讲到这里。下一章咱们聊聊如何把这些算法真正部署到 AUTOSAR 架构里。记住:理论再好,不上车都是白搭。