密码学基础(上):对称加密与非对称加密,哈希函数(SHA-256),数字签名原理(RSA/ECDSA)

各位同学,欢迎来到第二讲。今天我们要啃一块硬骨头——密码学基础。别紧张,我不会把你们按在数学公式里淹死。我会用实战的视角,带你们看看这些算法在VxWorks安全启动里到底扮演什么角色。

说实话,我刚入行时也觉得密码学是数学家的事。直到有一次,我在一个工控项目里,因为选错了签名算法,导致启动时间超了200毫秒,被客户骂得狗血淋头。从那以后,我明白了:工程师不需要证明算法,但必须懂怎么选、怎么用。

一、对称加密:一把钥匙开一把锁

对称加密,说白了就是加密和解密用同一个密钥。就像你家的门锁,用同一把钥匙锁门和开门。

常见的对称算法有AES、DES、SM4。在VxWorks安全启动场景里,我们几乎只用AES-256。为什么?因为它是NIST认证的标准,硬件加速支持也最好。

核心要点:

  • 加密速度快,适合大数据量
  • 密钥分发是最大痛点
  • 在安全启动中,常用于加密固件镜像

我在项目中遇到过一个问题:用AES加密固件后,解密时发现某些块解出来是乱码。排查了半天,原来是IV(初始化向量)没对齐。嗯,这里要注意——AES-CBC模式要求IV长度必须是16字节,多一个少一个都不行。

二、非对称加密:公钥私钥,各司其职

非对称加密就高级多了。它有一对密钥:公钥可以公开,私钥必须保密。你用公钥加密,只有私钥能解密;反过来,你用私钥签名,公钥可以验证。

你想想看,这解决了什么问题?密钥分发!在安全启动里,我们可以在产线上把公钥烧进芯片,私钥留在服务器上。这样即使芯片被破解,攻击者也拿不到私钥。

特性 对称加密 非对称加密
密钥数量 1个 2个(公钥+私钥)
速度 快(硬件加速可达Gbps) 慢(通常用于小数据)
典型算法 AES, SM4 RSA, ECDSA, SM2
安全启动用途 加密固件内容 签名验证

我个人习惯在VxWorks里用ECDSA而不是RSA。为什么?因为ECDSA的密钥更短,签名速度更快。同样是256位安全强度,RSA需要3072位密钥,而ECDSA只需要256位。在嵌入式设备上,这差别可大了去了。

三、哈希函数:数据的指纹

哈希函数,你可以把它想象成数据的指纹。不管输入多大,输出都是固定长度。而且,哪怕只改了一个比特,哈希值都会完全不一样。

SHA-256是现在最常用的哈希算法。它输出256位(32字节)的哈希值。在安全启动里,我们用它来校验固件的完整性。

实战技巧:

我曾经在调试一个启动失败的问题时,发现固件哈希总是对不上。后来发现,是BootROM在读固件时,把末尾的填充字节也算进去了。解决方案很简单:在计算哈希前,先明确数据边界。

这里有个坑要注意:SHA-256不是加密!它是单向的。你不能从哈希值反推出原始数据。所以,哈希函数不能用来加密数据,只能用来校验完整性。

四、数字签名:防伪与防篡改

数字签名,就是把哈希函数和非对称加密结合起来。流程是这样的:

  1. 对固件计算SHA-256哈希值
  2. 用私钥对哈希值加密,得到签名
  3. 把签名附加到固件后面
  4. 验证时,用公钥解密签名得到哈希值A
  5. 重新计算固件的哈希值B
  6. 比较A和B,一致则签名有效

你想想看,这保证了什么?第一,固件没有被篡改(哈希值变了签名就失效)。第二,固件确实来自合法发布者(只有持有私钥的人才能生成有效签名)。

重要警告:

千万不要在代码里硬编码私钥!我见过有厂商把私钥写在源码里,结果固件被反编译后,私钥直接暴露。那整个安全体系就形同虚设了。

五、RSA vs ECDSA:怎么选?

这个问题我经常被问到。直接给结论:

  • 选RSA的情况:你的芯片有硬件RSA加速器,或者需要兼容老旧系统。RSA的数学原理简单,实现起来不容易出错。
  • 选ECDSA的情况:追求性能,或者存储空间有限。ECDSA的签名更短,计算更快。

我个人更倾向ECDSA。记得有一次,我在一个Cortex-M4的芯片上做安全启动,RSA-2048签名验证花了将近1秒,换成ECDSA P-256后,降到了200毫秒。客户当场就竖了大拇指。

但ECDSA也有坑。它对随机数质量要求极高。如果随机数生成器有问题,私钥可能被推导出来。我曾经在项目中遇到过,因为硬件随机数发生器故障,导致ECDSA签名偶尔失败。排查了整整两天才找到原因。

六、在VxWorks中的实际应用

好了,理论讲完了。我们来看看在VxWorks里怎么用这些算法。

VxWorks提供了crypto子系统,支持OpenSSL和WolfSSL两种后端。我个人推荐用WolfSSL,因为它更轻量,适合嵌入式环境。

/* 示例:使用WolfSSL计算SHA-256 */
#include <wolfssl/ssl.h>

int compute_sha256(const unsigned char* data, int len, unsigned char* hash) {
    wc_Sha256 sha;
    int ret;
    
    ret = wc_InitSha256(&sha);
    if (ret != 0) return -1;
    
    ret = wc_Sha256Update(&sha, data, len);
    if (ret != 0) return -1;
    
    ret = wc_Sha256Final(&sha, hash);
    if (ret != 0) return -1;
    
    return 0;
}

这段代码看起来简单,但实际用的时候要注意:wc_Sha256Update可以多次调用,适合处理大文件。我一般会分块读取固件,每块1MB,边读边更新哈希。

避坑指南:

我曾经在VxWorks 6.9上遇到一个bug:WolfSSL的SHA-256在多线程环境下会崩溃。原因是内部全局变量没有加锁。解决方案是改用OpenSSL后端,或者给WolfSSL打补丁。所以,生产环境一定要做压力测试。

七、总结与下期预告

今天我们讲了密码学的基础:对称加密、非对称加密、哈希函数和数字签名。这些是安全启动的基石。你不需要记住所有数学细节,但一定要理解它们各自的作用和适用场景。

下节课,我们会深入VxWorks的安全启动流程,看看这些算法是怎么串联起来的。我会带你们一步步分析BootROM的签名验证逻辑,还会分享一个我在产线上遇到的真实案例——因为签名格式不对,导致整批设备无法启动。

好了,今天就到这里。有什么问题,欢迎课后交流。

课后练习:

1. 在VxWorks上实现一个简单的固件签名验证程序,使用ECDSA P-256。

2. 对比RSA-2048和ECDSA P-256的签名验证时间,记录结果。

3. 思考:如果哈希函数换成SHA-1,会有什么安全风险?