密钥体系基础:对称密钥与非对称密钥的区别、密钥生命周期、密钥分级管理策略

大家好,我是你们的嵌入式安全讲师。今天咱们聊聊密钥体系的基础。说实话,这章内容看着有点理论,但它是整个密钥烧录流程的根基。你想想看,连密钥是什么、怎么管都不清楚,后面烧录、存储、使用肯定要出大问题。

我个人习惯,讲理论之前先问个问题:为什么我们需要密钥? 说白了,密钥就是一把锁。你家的门锁,只有用对的钥匙才能打开。在嵌入式系统里,密钥就是那把数字钥匙,用来保护你的代码、数据、通信不被别人偷走或篡改。

对称密钥与非对称密钥的区别

先讲对称密钥。这个概念很简单:加密和解密用同一把钥匙。就像你和你老婆共用一把家门钥匙,你锁门,她开门,用的都是同一把。

对称密钥的优点是快,特别快。我在项目中用过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):临时生成,用于一次通信会话。用完即销毁,下次通信重新生成。

我画了一张图,帮你理解这个层级关系:

密钥分级管理结构图 根密钥(Root Key) 存储在HSM/SE中,永不离开 设备密钥(Device Key) 每个设备唯一,由根密钥派生/加密保护 会话密钥(Session Key) 临时生成,一次一密,用完即销毁 高等级密钥保护低等级密钥,层层递进 即使会话密钥泄露,也不影响根密钥安全

这种分级策略在实际项目中非常实用。比如我做的一个智能门锁项目:

  • 根密钥在芯片出厂时烧录到安全元件里,连我都不知道具体值。
  • 设备密钥由根密钥派生,每个门锁的密钥都不同。即使一个门锁被破解,其他门锁依然安全。
  • 会话密钥每次开锁时临时生成,用完就扔。就算有人抓包拿到了会话密钥,也只能解密这一次通信,下次就没用了。

核心要点:密钥分级管理的精髓是「层层保护,最小暴露」。根密钥是命根子,必须用最安全的方式保护;会话密钥是消耗品,用完就扔,不用心疼。

我的小技巧:在设计密钥体系时,先画一张类似上面的层级图,把每个密钥的用途、存储位置、生命周期标清楚。然后问自己三个问题:

  1. 这个密钥泄露了,影响范围有多大?
  2. 这个密钥怎么销毁?
  3. 这个密钥的备份方案是什么?

三个问题都回答清楚了,再开始写代码。

警告:千万不要把根密钥和设备密钥混在一起存储。我曾经见过一个产品,把根密钥和设备密钥都放在同一个Flash扇区里。结果设备密钥泄露后,攻击者顺藤摸瓜,把根密钥也读出来了。整个产品线的安全体系瞬间崩塌。

好了,这一章的内容就到这里。密钥体系是安全烧录的基础,理解清楚对称与非对称的区别、生命周期的每个阶段、以及分级管理的策略,后面讲烧录流程时你才能跟上节奏。

可可精品资料库