4、非对称加密算法(ECC/RSA):椭圆曲线数字签名算法(ECDSA)、RSA-PSS签名验证、密钥对生成与存储

好,我们进入第四章。这一章讲的是非对称加密,说白了就是公钥和私钥那套东西。在汽车ECU里,这玩意儿是安全启动和通信加密的基石。我个人习惯把非对称加密比作一把锁——公钥是锁,谁都能拿来锁上;私钥是钥匙,只有你能打开。

今天重点聊三个东西:ECDSARSA-PSS,还有密钥对的生成与存储。嗯,咱们一个一个来。

4.1 椭圆曲线数字签名算法(ECDSA)

ECDSA,全称Elliptic Curve Digital Signature Algorithm。说白了,就是用椭圆曲线来做签名。为什么汽车行业越来越喜欢它?因为同样的安全强度下,它的密钥更短

举个例子:

  • RSA 2048位的安全级别,ECDSA用256位就够了
  • 计算量小,适合ECU这种资源受限的环境
  • 签名速度快,验证速度也快

我在项目中遇到过一个问题:某款MCU的硬件加速器只支持RSA,不支持ECC。结果我们不得不把ECDSA签名验证放在软件里跑,那叫一个慢。所以选芯片时,一定要确认硬件是否支持ECC加速。

核心流程:

  1. 签名方用私钥对消息哈希签名
  2. 验证方用公钥验证签名
  3. 签名结果是一对整数 (r, s)

代码示例(伪代码,实际项目中常用mbedTLS或OpenSSL):

// 签名
ecdsa_sign(private_key, message_hash, &r, &s);

// 验证
ecdsa_verify(public_key, message_hash, r, s);

这里要注意:随机数质量。ECDSA签名时需要一个随机数k,如果k重复了,私钥就暴露了。我曾经见过一个项目,因为随机数生成器没初始化好,导致两个签名用了同一个k,结果私钥被算出来了。嗯,这是个坑。

警告:ECDSA的随机数k绝对不能重复!建议使用硬件真随机数生成器(TRNG)。

4.2 RSA-PSS签名验证

RSA-PSS,全称RSA Probabilistic Signature Scheme。相比传统的PKCS#1 v1.5签名,PSS模式更安全。为什么?因为它引入了随机盐值(salt),让同样的消息每次签名结果都不一样。

你想想看,如果每次签名都一样,攻击者就可以做选择明文攻击。PSS模式把这个漏洞堵上了。

RSA-PSS的流程:

  • 消息哈希后,填充盐值和固定字节
  • 用私钥加密(实际是模幂运算)
  • 验证时,用公钥解密,检查填充格式

代码示例:

// RSA-PSS签名
rsa_sign_pss(private_key, message_hash, salt_len, &signature);

// RSA-PSS验证
rsa_verify_pss(public_key, message_hash, signature, salt_len);

我个人建议:新项目尽量用RSA-PSS,别用PKCS#1 v1.5。虽然v1.5兼容性好,但安全性差一截。我在一个T-Box项目里就吃过亏——客户要求兼容旧设备,只能用v1.5,结果安全审计被打了回来。

提示:RSA-PSS的盐值长度一般设为哈希长度。比如SHA-256就用32字节盐值。

4.3 密钥对生成与存储

密钥对生成,说白了就是算出一对公钥和私钥。ECC和RSA的生成方式完全不同:

算法 生成方式 速度 典型长度
RSA 找两个大素数,算模数 慢(尤其是2048位以上) 2048 / 4096位
ECC 选曲线,算基点倍数 256 / 384位

生成密钥对时,我建议:

  • RSA:在产线或安全环境中生成,私钥写入HSM(硬件安全模块)
  • ECC:可以在ECU内部生成,前提是有TRNG

存储方面,这是个大话题。私钥绝对不能明文存!我见过一个项目,私钥直接写在Flash里,结果被读出来,整个安全体系就崩了。

存储建议:

  • 私钥存HSM或安全元件(SE)
  • 如果MCU没有HSM,用OTP(一次性可编程)区域
  • 公钥可以存Flash,但要有完整性校验

代码示例(使用mbedTLS生成ECC密钥对):

mbedtls_ecdsa_context ctx;
mbedtls_ecdsa_init(&ctx);
mbedtls_ecp_group_load(&ctx.grp, MBEDTLS_ECP_DP_SECP256R1);
mbedtls_ecdsa_genkey(&ctx, mbedtls_ctr_drbg_random, &ctr_drbg);
// 私钥存在ctx.d,公钥存在ctx.Q

嗯,这里要注意:生成密钥对时,一定要用安全的随机数。如果随机数质量差,密钥就可能被预测。我曾经在实验室里用了一个伪随机数生成器(PRNG)来生成RSA密钥,结果发现生成的素数有规律,差点出事。

警告:绝对不要用rand()或类似的伪随机函数生成密钥!必须用硬件TRNG或经过认证的DRBG。

4.4 实际项目中的选择建议

说了这么多,到底选ECC还是RSA?我个人的经验是:

  • 新平台:优先ECC(P-256或P-384),性能好,密钥短
  • 兼容旧系统:可能得用RSA,因为很多老设备只支持RSA
  • 安全启动:签名用ECDSA,验证速度快
  • 通信加密:可以用ECDH做密钥交换,再用对称加密

最后说一句:算法本身安全,不代表实现安全。侧信道攻击、时序攻击、故障注入,这些都能绕过算法。所以一定要用经过认证的加密库,比如mbedTLS、OpenSSL,或者硬件加速器。

好,这一章就到这儿。下一章我们讲哈希函数和消息认证码,那是签名的基础。