4、加密算法实战:AES、RSA、ECC在嵌入式中的实现、密钥管理、硬件加速器使用
加密算法在嵌入式系统里,说白了就是给数据加把锁。我做了这么多年嵌入式安全,见过太多因为加密没做好导致设备被攻破的案例。今天咱们就聊聊AES、RSA、ECC这三种主流算法,在嵌入式环境里到底怎么落地。
4.1 AES:对称加密的扛把子
AES是目前最常用的对称加密算法。为什么?因为它快,而且硬件支持好。我习惯在需要加密大量数据时首选AES,比如固件升级包、患者数据流。
嵌入式实现AES,有几个关键点要注意:
- 密钥长度:128位够用,256位更安全。但256位会慢一些,看你的MCU性能。
- 工作模式:ECB模式千万别用!我见过有人图省事用ECB,结果加密后的图像还能看出轮廓。CBC或GCM模式更靠谱。
- 初始化向量(IV):每次加密都要用不同的IV,别偷懒。
核心要点:AES的密钥必须安全存储,不能硬编码在代码里。我曾在项目中看到有人把AES密钥写在头文件里,结果固件被dump出来,密钥直接暴露。
下面是一个典型的AES-CBC实现片段:
// 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[64] = "患者数据...";
unsigned char output[64];
mbedtls_aes_init(&aes_ctx);
mbedtls_aes_setkey_enc(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT,
sizeof(input), iv, input, output);
mbedtls_aes_free(&aes_ctx);
我的经验:用mbedTLS库时,记得每次加密后重新设置IV。我曾经因为复用IV,导致两次加密结果相同,差点被攻击者利用。
4.2 RSA:非对称加密的老将
RSA适合加密小数据,比如密钥交换、数字签名。在嵌入式里,RSA的痛点就是慢。1024位RSA在低端MCU上可能要几秒钟。
我个人建议:
- 密钥长度至少2048位,1024位已经不安全了
- 公钥可以公开,私钥必须安全存储
- 不要用RSA加密大量数据,效率太低
RSA实现时,最头疼的是大数运算。嵌入式MCU没有硬件除法器,做模幂运算很慢。我曾在STM32F4上跑RSA-2048签名,一次操作要800ms,后来改用硬件加速器才降到20ms。
避坑指南:我曾经在项目里用RSA做密钥交换,结果发现随机数生成器不够随机,导致私钥被预测。记住,RSA的安全性高度依赖随机数质量。
4.3 ECC:新一代的宠儿
ECC用更短的密钥提供相同安全等级。256位ECC相当于3072位RSA。在嵌入式里,ECC的优势很明显:省内存、省带宽、省电量。
ECC的常见应用:
- ECDH密钥交换
- ECDSA数字签名
- TLS握手
实现ECC时,曲线选择很重要。我习惯用NIST P-256或Curve25519。Curve25519在嵌入式里更友好,因为它避免了侧信道攻击的坑。
// ECDH 密钥交换示例(使用micro-ecc库)
#include "uECC.h"
const struct uECC_Curve_t * curve = uECC_secp256r1();
uint8_t private_key[32];
uint8_t public_key[64];
uint8_t shared_secret[32];
// 生成密钥对
uECC_make_key(public_key, private_key, curve);
// 计算共享密钥
uECC_shared_secret(public_key, private_key, shared_secret, curve);
我的习惯:ECC私钥生成后,立即擦除临时缓冲区。防止调试器或内存dump泄露私钥。
4.4 密钥管理:最容易被忽视的环节
算法选得再好,密钥管理一塌糊涂,等于白干。我见过太多嵌入式设备,密钥直接明文存储,或者用简单的异或混淆。
密钥管理要点:
| 存储位置 | 安全等级 | 推荐场景 |
|---|---|---|
| MCU内部Flash | 低 | 仅用于测试 |
| 安全元件(SE) | 高 | 生产环境 |
| TPM芯片 | 高 | PC级嵌入式 |
| OTP存储 | 中 | 一次性写入 |
我建议:
- 生产环境用安全元件存储密钥
- 密钥分区存储,不要全放在一个地方
- 定期更换密钥,尤其是设备生命周期长的
我曾经踩过的坑:有一次设备批量生产,发现所有设备的密钥都一样。原因是生产脚本里写死了密钥种子。从那以后,我坚持每台设备单独生成密钥。
4.5 硬件加速器:让加密飞起来
现代MCU基本都带硬件加密加速器。比如STM32的CRYP外设、NXP的CAAM模块。用硬件加速器,加密速度能提升10-100倍。
使用硬件加速器的步骤:
- 初始化外设时钟和DMA
- 配置算法模式和密钥
- 准备输入输出缓冲区
- 启动加密操作(通常用DMA)
- 等待完成中断
// STM32 AES硬件加速示例
HAL_CRYP_Init(&hcryp);
HAL_CRYP_SetKey(&hcryp, key, AES_KEY_SIZE_128);
HAL_CRYP_AESCBC_Encrypt(&hcryp, input, AES_BLOCK_SIZE, output, TIMEOUT);
我的经验:用硬件加速器时,注意DMA缓冲区对齐。我曾经因为缓冲区没对齐,导致DMA传输错误,加密结果全乱。
硬件加速器的优势:
- 速度快,不占CPU
- 抗侧信道攻击(硬件实现更安全)
- 功耗低
但要注意,不是所有MCU的硬件加速器都支持所有算法。选型时要确认清楚。我习惯在项目初期就确定加密需求,然后选带对应加速器的MCU。
总结一下:AES做数据加密,RSA做密钥交换和签名,ECC是未来的趋势。密钥管理是安全的基础,硬件加速器是性能的保障。做嵌入式安全,这三样缺一不可。
嗯,今天就聊到这儿。下一章咱们聊聊安全启动和固件签名,那也是个容易踩坑的地方。