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倍。

使用硬件加速器的步骤:

  1. 初始化外设时钟和DMA
  2. 配置算法模式和密钥
  3. 准备输入输出缓冲区
  4. 启动加密操作(通常用DMA)
  5. 等待完成中断
// 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是未来的趋势。密钥管理是安全的基础,硬件加速器是性能的保障。做嵌入式安全,这三样缺一不可。

嗯,今天就聊到这儿。下一章咱们聊聊安全启动和固件签名,那也是个容易踩坑的地方。