密钥体系基础:对称密钥与非对称密钥的区别、密钥生命周期、密钥分级管理策略
大家好,我是你们的嵌入式安全讲师。今天咱们聊聊密钥体系的基础。说实话,这章内容看着有点理论,但它是整个密钥烧录流程的根基。你想想看,连密钥是什么、怎么管都不清楚,后面烧录、存储、使用肯定要出大问题。
我个人习惯,讲理论之前先问个问题:为什么我们需要密钥? 说白了,密钥就是一把锁。你家的门锁,只有用对的钥匙才能打开。在嵌入式系统里,密钥就是那把数字钥匙,用来保护你的代码、数据、通信不被别人偷走或篡改。
对称密钥与非对称密钥的区别
先讲对称密钥。这个概念很简单:加密和解密用同一把钥匙。就像你和你老婆共用一把家门钥匙,你锁门,她开门,用的都是同一把。
对称密钥的优点是快,特别快。我在项目中用过AES-128,加密一个128位的数据块,在Cortex-M4上也就几十个时钟周期。缺点呢?密钥分发是个大麻烦。你想想看,如果我要把密钥发给远端的设备,怎么安全地传过去?如果密钥在传输过程中被截获,那整个加密体系就废了。
非对称密钥就不一样了。它有两把钥匙:公钥和私钥。公钥可以公开,谁都可以拿;私钥自己藏着,谁都不给。用公钥加密的数据,只有对应的私钥能解开。反过来,用私钥签名的数据,用公钥就能验证签名是否有效。
我记得有一次做OTA升级方案,设备端需要验证服务器下发的固件包是否被篡改。用对称密钥的话,设备里得存一个密钥,服务器也得存同一个密钥。万一设备被破解,密钥泄露,整个产品线的设备都得遭殃。后来改用非对称密钥,设备里只存公钥,服务器用私钥签名固件。设备拿到固件后,用公钥验签就行。就算设备被破解,泄露的也只是公钥,对服务器没有威胁。
这里我给大家一个对比表格,方便记忆:
| 特性 | 对称密钥 | 非对称密钥 |
|---|---|---|
| 密钥数量 | 1个(加密解密共用) | 2个(公钥+私钥) |
| 运算速度 | 快(适合大数据量) | 慢(适合小数据量) |
| 密钥分发 | 困难(需要安全通道) | 容易(公钥可公开) |
| 典型算法 | AES、DES、SM4 | RSA、ECC、SM2 |
| 典型用途 | 数据加密、通信加密 | 数字签名、密钥交换 |
实际项目中,我经常把两者结合起来用。比如HTTPS协议,先用非对称密钥交换一个临时对称密钥,然后用对称密钥加密后续的通信数据。这样既解决了密钥分发问题,又保证了加密速度。
密钥生命周期
密钥不是永生的。它从出生到死亡,经历一个完整的生命周期。我把它分成五个阶段:生成、分发、存储、使用、销毁。每个阶段都有坑,我一个个说。
1. 生成
密钥生成是第一步,也是最容易被忽视的一步。很多人觉得,随便找个随机数生成器,跑一下就有了。错!随机数生成器必须用硬件真随机数发生器(TRNG),不能用软件伪随机数。我曾经见过一个项目,用C语言的rand()函数生成密钥,结果每次上电生成的密钥都一样,那还加密个啥?
另外,密钥长度要选对。AES至少128位,RSA至少2048位,ECC至少256位。别为了省那点存储空间,选个短密钥,结果被暴力破解了。
2. 分发
分发是密钥生命周期里最危险的一环。密钥在传输过程中,就像钞票在街上扔着,谁捡到就是谁的。所以,密钥分发必须走安全通道。
常见的做法有几种:
- 预置:在生产阶段直接把密钥烧录到设备里。这是最安全的方式,因为密钥从未离开过安全环境。
- 密钥协商:设备之间通过Diffie-Hellman等协议,在不安全的通道上协商出一个共享密钥。即使有人监听,也拿不到密钥。
- 公钥加密传输:用接收方的公钥加密对称密钥,然后发送。只有接收方用自己的私钥才能解开。
我个人最推荐预置方式。因为嵌入式设备一旦部署到现场,再想安全地分发密钥,难度会大很多。
3. 存储
密钥存储是另一个重灾区。很多开发者把密钥直接写在代码里,或者存在Flash的固定地址。这等于把家门钥匙挂在门上,谁都能看到。
正确的做法是:密钥必须存储在安全硬件中。比如:
- 安全元件(SE):独立的加密芯片,密钥存在里面,CPU只能通过接口调用加解密功能,无法直接读取密钥。
- 硬件安全模块(HSM):类似SE,但功能更强大,通常用于服务器端。
- TrustZone / TEE:在CPU内部划分一个安全区域,密钥存在安全世界里,普通世界无法访问。
如果硬件不支持这些,至少也要对密钥进行加密存储。用设备唯一ID或PUF(物理不可克隆函数)派生的密钥,去加密主密钥,然后存到Flash里。这样即使Flash被读出,攻击者也拿不到明文密钥。
4. 使用
密钥在使用时,要遵循最小权限原则。什么意思呢?就是每个密钥只做一件事。比如:
- 通信加密密钥,只用于加密通信数据。
- 固件签名密钥,只用于签名固件。
- 身份认证密钥,只用于设备认证。
不要一个密钥包打天下。我在项目中遇到过,有人把AES密钥既用于加密通信,又用于加密存储,还用于签名。结果通信密钥泄露后,整个系统的所有加密数据都被破解了。
另外,密钥在使用过程中,不要暴露到CPU的通用寄存器或内存中。如果必须使用,用完立即擦除。我记得有一次调试,发现密钥在内存里残留了很长时间,被调试器读出来了。从那以后,我写代码都会在加解密函数返回前,用memset把临时缓冲区清零。
5. 销毁
密钥到期了、设备退役了、或者怀疑密钥泄露了,都需要销毁密钥。销毁不是简单地删除文件,而是要物理上不可恢复。
对于存储在Flash或EEPROM中的密钥,可以用多次覆写的方式销毁。比如先写0xFF,再写0x00,再写随机数,重复几次。对于存储在安全元件中的密钥,调用安全元件的销毁指令,让芯片内部自动擦除。
我曾经犯过一个错误:设备退役后,只是把Flash里的密钥标记为无效,没有真正擦除。结果有人用JTAG把Flash读出来,恢复了密钥。嗯,从那以后,我再也不敢偷懒了。
密钥分级管理策略
密钥分级管理,说白了就是把密钥分成不同等级,高等级密钥保护低等级密钥。这样做的好处是:即使低等级密钥泄露,高等级密钥依然安全,整个系统的根基不会动摇。
常见的分级策略是三层结构:
- 根密钥(Root Key):最高等级,通常存储在安全元件或HSM中,永远不离开安全硬件。用于派生或保护下一级密钥。
- 设备密钥(Device Key):每个设备唯一,由根密钥派生或加密保护。用于设备身份认证、通信加密等。
- 会话密钥(Session Key):临时生成,用于一次通信会话。用完即销毁,下次通信重新生成。
我画了一张图,帮你理解这个层级关系:
这种分级策略在实际项目中非常实用。比如我做的一个智能门锁项目:
- 根密钥在芯片出厂时烧录到安全元件里,连我都不知道具体值。
- 设备密钥由根密钥派生,每个门锁的密钥都不同。即使一个门锁被破解,其他门锁依然安全。
- 会话密钥每次开锁时临时生成,用完就扔。就算有人抓包拿到了会话密钥,也只能解密这一次通信,下次就没用了。
核心要点:密钥分级管理的精髓是「层层保护,最小暴露」。根密钥是命根子,必须用最安全的方式保护;会话密钥是消耗品,用完就扔,不用心疼。
我的小技巧:在设计密钥体系时,先画一张类似上面的层级图,把每个密钥的用途、存储位置、生命周期标清楚。然后问自己三个问题:
- 这个密钥泄露了,影响范围有多大?
- 这个密钥怎么销毁?
- 这个密钥的备份方案是什么?
三个问题都回答清楚了,再开始写代码。
警告:千万不要把根密钥和设备密钥混在一起存储。我曾经见过一个产品,把根密钥和设备密钥都放在同一个Flash扇区里。结果设备密钥泄露后,攻击者顺藤摸瓜,把根密钥也读出来了。整个产品线的安全体系瞬间崩塌。
好了,这一章的内容就到这里。密钥体系是安全烧录的基础,理解清楚对称与非对称的区别、生命周期的每个阶段、以及分级管理的策略,后面讲烧录流程时你才能跟上节奏。
可可精品资料库