4、混合加密方案:结合AES与RSA、会话密钥生成、体温计数据加密流程设计

好,咱们进入正题。前面聊了对称加密和非对称加密各自的优缺点,你可能会想:那到底用哪个?我的答案是——全都要

混合加密,说白了就是让AES和RSA搭伙干活。AES速度快,适合加密体温数据这种大块内容;RSA安全但慢,适合加密那个小小的“钥匙”。这个思路在物联网设备里非常常见,我参与过的几个医疗项目,基本都是这个套路。

4.1 为什么非要混合?

你想想看,如果只用AES,那密钥怎么安全地传给服务器?明文传?那跟没加密一样。如果只用RSA,加密一段体温数据(比如32字节)倒还行,但体温计一次上报可能包含几十条历史记录,RSA加密起来就太慢了,设备电池扛不住。

所以混合方案的核心思路就是:用RSA保护AES密钥,用AES保护实际数据

一句话总结:会话密钥(AES密钥)由客户端随机生成,用服务器的RSA公钥加密后传输。服务器用私钥解密得到AES密钥,后续通信都用这个AES密钥加密。

4.2 会话密钥生成——别偷懒用固定值

会话密钥,就是每次通信时临时生成的AES密钥。我个人习惯用256位密钥,也就是32字节。为什么?因为AES-256目前还是牢不可破的。

生成方式很简单,但有个坑——千万别用随机数种子固定的伪随机数生成器。我在一个项目里见过有人用C语言的rand()生成密钥,结果每次设备重启后密钥都一样,这跟没加密有啥区别?

正确的做法是使用硬件随机数生成器(TRNG),或者至少用操作系统提供的安全随机数接口。比如在嵌入式设备上,可以用芯片自带的RNG外设。

// 伪代码示例:生成32字节的AES-256会话密钥
uint8_t session_key[32];
// 使用硬件随机数生成器
trng_generate_random_bytes(session_key, 32);
// 或者使用软件安全的随机数生成器
// 注意:不要用 rand() !!!

我的经验:曾经有个体温计项目,因为用了伪随机数生成器,导致所有设备的会话密钥都相同。测试时没发现,直到安全审计才暴露。从那以后,我坚持所有密钥生成必须用硬件随机源。

4.3 体温计数据加密流程设计

好,咱们把整个流程串起来。假设体温计要上报一条体温数据:36.5°C,测量时间2024-01-15 08:30:00,设备ID为TEMP-001。

4.3.1 第一步:生成会话密钥

体温计上电后,生成一个随机的32字节AES密钥。这个密钥只用于本次会话,下次连接时重新生成。

4.3.2 第二步:用RSA公钥加密会话密钥

体温计内置了服务器的RSA公钥(2048位或以上)。用这个公钥加密刚才生成的AES密钥。注意,RSA加密的数据长度有限制,2048位RSA最多只能加密256字节,而AES-256密钥只有32字节,完全够用。

// 加密会话密钥
uint8_t encrypted_key[256]; // RSA-2048输出256字节
rsa_encrypt(server_public_key, session_key, 32, encrypted_key);

4.3.3 第三步:用AES加密体温数据

用会话密钥加密体温数据。这里我建议使用AES-GCM模式,因为它同时提供加密和完整性校验。CBC模式也行,但需要额外处理填充和MAC。

// 体温数据明文
uint8_t plaintext[] = {
    0x01,       // 数据类型:体温
    0x00, 0x01, // 设备ID高字节
    0x36, 0x05, // 体温值:36.5°C(放大10倍存储)
    // ... 时间戳等其他字段
};
// 使用AES-GCM加密
uint8_t ciphertext[sizeof(plaintext)];
uint8_t tag[16]; // GCM认证标签
aes_gcm_encrypt(session_key, plaintext, sizeof(plaintext), ciphertext, tag);

4.3.4 第四步:组装数据包并发送

把加密后的会话密钥、加密后的体温数据、以及GCM认证标签打包在一起,发送给服务器。

字段 长度 说明
加密的会话密钥 256字节 RSA加密后的AES密钥
加密的体温数据 可变 AES-GCM加密后的密文
GCM认证标签 16字节 用于完整性校验
设备ID(明文) 4字节 用于服务器识别设备

4.3.5 第五步:服务器解密

服务器收到数据包后:

  1. 用私钥解密出会话密钥
  2. 用会话密钥解密体温数据
  3. 验证GCM标签,确保数据未被篡改

注意:我曾经遇到过一个问题——体温计每次上报都重新生成会话密钥,导致服务器端需要频繁进行RSA解密操作。对于大规模部署(比如上万台设备),这会成为性能瓶颈。我的建议是:会话密钥可以复用一段时间(比如1小时),但不要超过这个时间,否则安全性会下降。

4.4 实际项目中的避坑指南

  • 密钥存储:体温计里的RSA私钥?不对,体温计只存公钥,私钥在服务器端。千万别搞反了!
  • 随机数质量:我之前提过,别用rand()。嵌入式设备上,如果硬件RNG不可用,可以考虑用芯片的ADC噪声作为随机源。
  • 数据包大小:RSA加密后的会话密钥固定256字节,加上体温数据,整体包大小要控制在MTU以内(通常1500字节)。如果体温数据太多,可以分片传输。
  • 重放攻击:在数据包里加入时间戳和序列号,服务器端做去重校验。这个我在后面章节会详细讲。

一个小技巧:如果你用的是AES-GCM,记得每次加密时使用不同的随机IV(初始化向量)。IV不需要加密,可以明文传输。但同一个密钥下,IV绝对不能重复,否则GCM的安全性会崩溃。

嗯,混合加密方案说到这里,基本就清楚了。说白了就是:用RSA解决密钥分发问题,用AES解决数据加密效率问题。这个方案在医疗物联网领域已经非常成熟,我经手的几个体温计项目都是这么做的,安全审计也都能通过。

下一章咱们聊聊密钥的生命周期管理——密钥怎么更新?怎么撤销?设备丢了怎么办?这些都是实际落地时躲不开的问题。