ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

硬件加密与软件加密的区别:从密钥存储到安全芯片选型实践

2026/9/9 2:19:10 拓冰建站 浏览量
硬件加密与软件加密的区别:从密钥存储到安全芯片选型实践 我最早被问到“芯片硬件加密和软件加密到底啥区别”是在接一个智能门锁项目的时候。客户拿着需求文档上面写着“必须支持硬件加密”但追问下去对方其实也说不清硬件加密到底硬在哪儿软件加密又软在哪里。这个问题在嵌入式圈子里特别常见尤其是这几年物联网设备越来越多大家开始关心固件保护、通信安全、防抄板自然就会碰到这个概念。先说结论硬件加密和软件加密不是“同一个算法用两种方式写一遍”那么简单而是密钥存放、计算位置、防攻击能力、性能开销这几个维度上的系统性差异。这篇内容我就用自己实际调过的芯片和踩过的坑把这两条路的底层逻辑、安全边界和选型方法一次讲清楚。1. 硬件加密和软件加密的底层逻辑差异1.1 先搞懂“加密”到底在做什么不管是AES、RSA还是国密SM4加密本质上都是数学运算。以AES-128为例就是把128位明文数据用128位密钥经过若干轮“字节代换、行移位、列混淆、轮密钥加”的计算最后得到128位密文。整个过程对计算单元的要求就是能算加法和查表能存数据能按顺序执行操作。所以在最底层加密并不“神秘”它需要的资源是三个算法逻辑、密钥、运行环境。软件加密和硬件加密的差别其实就藏在这三个资源的位置和属性上。这里有个常见的理解误区很多人觉得“用C语言调一个AES函数”是软件加密“芯片支持AES指令集或者有AES外设”就是硬件加密。这个说法方向对但不完整。硬件加密的精髓不只在“算得快”更在于“密钥和运算过程被包在一个外界碰不到的保护壳里”。1.2 软件加密通用CPU上跑数学函数软件加密就是在MCU或者SoC的通用CPU核心里通过软件代码来实现密码算法。你在STM32F103上调用mbedTLS库里的AES函数在ESP32上跑TinyCrypt做HMAC在Linux服务器上用OpenSSL算RSA本质上都属于软件加密。软件加密的特点非常直白密钥以明文形式存在Flash或内存里。哪怕你用一个全局数组存密钥编译器把它放在某个地址上调试器一读就能看到。运算过程发生在CPU流水线里功耗、执行时间都和具体数据、当前执行的指令强相关这给侧信道攻击留下了空间。算法是通用的可以灵活换想用AES就AES想换国密SM4就SM4只要能编译过就都能跑。代价是占用CPU时间尤其是非对称算法RSA、ECC运算量大到会在低主频MCU上卡几十毫秒甚至几百毫秒。不是说软件加密不能用。很多场景下比如设备只做一次性鉴权、数据不涉及高价值机密、攻击者也完全接触不到设备外壳那软件加密完全够用。它的安全问题更多发生在“攻击者能拿到设备、能读Flash、能上调试器”的场合。1.3 硬件加密专用引擎加上隔离边界硬件加密这个词在不同语境下指的东西不完全一样但在芯片层面它通常指一条相对独立的安全“生产线”。这条生产线上有专用的密码算法引擎比如AES加速器、RSA协处理器、有独立的密钥存储比如OTP、eFuse、安全Flash区或者安全RAM还可能带真随机数发生器TRNG、篡改检测、总线加密这些配套模块。以我经常用的ATECC608A这种独立安全芯片来说密钥一旦写入芯片内部的保险丝存储区主控CPU只能向它下发“用密钥X对数据做签名”这样的指令它算完之后把结果返回但密钥本身读不出来。主MCU不碰密钥这就是硬件隔离的价值。另一种形态是MCU片内集成加密引擎比如STM32系列里带AES外设的型号、GD32部分带国密算法加速的型号运算在专门电路里完成但密钥存储方式需要看具体实现有的芯片有安全密钥区有的只是“运算加速器”密钥还是要放在Flash里那安全等级就差一些。顺便提一句现在不少SoC芯片比如RK3588这一类带TrustZone安全岛、TEE可信执行环境的处理器它的“硬件加密”又复杂一层既有芯片底层的密码学引擎也有运行在安全世界的OP-TEE固件密钥由安全子系统统一管理普通Linux应用完全碰不到。这种属于上一级的“硬件信任根”方案安全性更强但开发和调试难度也明显更高。1.4 一张表看懂核心差异对比维度软件加密硬件加密运算执行位置通用CPU核心专用密码学引擎/协处理器密钥存储位置Flash/内存明文存储安全存储区OTP/eFuse/安全RAM密钥是否可被主控读出可以通常不可读CPU占用率高特别是非对称算法低硬件引擎独立完成抗侧信道攻击能力弱强固定时间执行、掩码、功耗均衡设计抗物理攻击能力弱强有金属屏蔽层、篡改检测等灵活性高算法可随时改低受限于硬件支持的算法集功耗高CPU高负荷低专用电路效率高成本零额外成本增加芯片面积或独立芯片成本2. 实际芯片场景中的硬件加密形态2.1 MCU内置密码学外设STM32、GD32、ESP32上的真实情况很多嵌入式工程师第一次接触硬件加密就是从MCU自带的加密外设开始的。以STM32为例STM32L0、L4等系列带独立的AES硬件外设STM32H723这类高性能型号上CRYP外设支持AES-128/192/256和更多算法。这个外设的作用是把AES的轮运算从CPU代码里搬到一个固定电路里完成。这样做带来的直接好处是加密16字节数据CPU只需要往数据寄存器里写东西然后等待结果标志位整个过程几乎是微秒级主内核可以去跑别的事情。不过MCU内置AES外设有个非常容易踩的坑它只加速“运算”不保证“密钥安全”。如果密钥数组还是写死在Flash里那攻击者照样用SWD调试接口或者读固件的方式把密钥翻出来。这时候你只能说“使用了硬件加速的AES”不能说“硬件加密保护了我的密钥”。更实用的做法是配合MCU的读保护RDP、唯一ID、一次性编程eFuse等手段。比如把某一把密钥烧录到芯片不可读的OTP区启动时让固件去读并协助AES外设做运算这样密钥才真正和外界隔离。GD32系列很多型号也集成了加密加速引擎特别是一些面向国密场景的芯片会直接支持SM3、SM4硬件计算在需要合规的场合非常省事。ESP32-C3、ESP32-S3这些Wi-Fi/蓝牙SoC同样内置AES、SHA、RSA加速器但它们的安全模型偏TEE方向使用时要配合Secure Boot和Flash加密一起用单独调用加密引擎也很难说得上完整的硬件保护。2.2 外置独立安全芯片密钥焊死在保险柜里如果说MCU内置AES外设更像是“家里雇了一个算账很快的助手但账本放在桌上”那独立安全芯片就是“账本锁在银行的保险柜里你需要查询时只能是银行帮你看完把结果告诉你”。ATECC608A是我用得最多的独立安全芯片之一。它的核心设计思路是密钥在出厂前或产线阶段写入芯片写入之后从任何接口都读不回来。主机可以通过I2C请求它用内部密钥对一段数据做ECDSA签名或者做AES加密但主机永远拿不到密钥本体。这种方案特别适合防抄板、固件版权保护、配件认证这类场景。比如做一个医疗配件主机的MCU在开机时给安全芯片发一个随机数安全芯片用内部密钥签名后返回主机校验通过才继续工作。哪怕仿造者把整个MCU固件都复制走了他没有主芯片内部对应的公钥或者没有安全芯片里的私钥照样仿不出来。独立安全芯片的代价是多一颗物料、多一条I2C或SPI总线、多一段产线烧录密钥的管理流程。BOM成本增加几块钱但对高价值产品来说这可能是整个产品线最划算的安全投入。类似方案还有NXP的SE050、英飞凌的OPTIGA系列原理大同小异选择时主要看算法支持、温度等级、供货稳定性和产线工具链。2.3 SoC内部的TrustZone安全世界RK3588这类高级形态RK3588这类应用处理器上的“硬件加密”又不一样了。它的CPU核心支持TrustZone技术芯片内部有多个安全启动只读存储器、OTP密钥存储、Crypto Extension加密扩展同时还运行一个单独的TEE操作系统比如OP-TEE。在这种架构里普通Linux系统跑在“非安全世界”密钥相关的操作放在“安全世界”执行。即使Linux内核被攻破、应用被植入恶意代码攻击者拿到的也只是非安全世界的内存视图隔离的安全世界根本进不去。加上Secure Boot机制启动过程中每一级代码都要验签芯片只运行签名正确的固件这等于把从设备上电到应用运行整条链路的信任基础都建立在了硬件上。但这种方案的开发复杂度也是三档里最高的。光是把密钥烧进eFuse、配置Security TrustZone Controller、调试可信固件TF-A这几个环节就足够让一个团队忙上几周。而且一旦安全启动配置完成普通调试器可能连芯片都连不上很多不熟悉安全机制的工程师会在这时候卡壳。我的建议是除非产品确实需要跑Linux系统、而且要防的是“有能力拆机并尝试读写Flash甚至注入攻击”的对手否则用普通MCU加独立安全芯片可能更容易达到安全目标。3. 性能、密钥存储和被攻破难度到底差在哪3.1 性能对比CPU占用、吞吐量和功耗做过通信加密的朋友应该对性能差异有直观感受。我曾在72 MHz的Cortex-M3芯片上用纯软件实现AES-128-CBC单次加密1 KB数据大概耗时1~2毫秒左右取决于编译器优化级别和查表策略。这听起来不多但如果是持续传输几百KB传感器数据CPU基本就一直在做加密运算主业务逻辑和通信协议栈都得被迫降低优先级。同样一块芯片如果内置AES硬件外设同样的1 KB数据加密耗时能降到几十微秒量级而且整个过程由DMA搬运CPU几乎不参与。两者的吞吐差距可以达到几十倍甚至上百倍。当然这个数字和具体芯片主频、总线时钟、AES外设时钟配置都有关系不同MCU差异很大不要拿某个型号的极限值去套另一个型号。更明显的性能差距出现在非对称算法上。比如用软件在MCU上做一次RSA-2048签名耗时常常在几百毫秒到秒级这不仅影响用户体验高负荷下还可能引发看门狗超时。改用带RSA硬件加速或者独立安全芯片后一次签名可以缩短到几十毫秒甚至几毫秒。功耗方面专用硬件电路比通用CPU执行同一运算的效率高得多对电池供电设备来说完成一次签名的时间越短平均功耗越低这也是我在低功耗产品上优先选硬件加密的原因之一。3.2 密钥会不会被读走Flash明文存储是个大问题软件加密最大的软肋是密钥的存放方式。大多数MCU的Flash并不防读。只要攻击者能通过调试接口SWD/JTAG、Bootloader漏洞、或者直接拆下Flash芯片物理读取就能拿到里面的固件镜像再用binwalk一类的工具提取字符串和数组AES密钥、API密钥基本就暴露了。有人会想“那我把固件整体加密行不行”这就又需要一个解密的密钥兜兜转转还是回到“密钥放哪”的问题。还有人试图通过混淆数组、拆开存储、异或一个常数来藏密钥这些办法只能防住最简单的静态分析对能动态调试的人来说基本形同虚设。硬件加密解决的就是这个问题。独立安全芯片和带eFuse/OTP安全区的MCU都把密钥放在只能被内部安全状态机访问的存储单元里。CPU只能“用”这个密钥不能“读”这个密钥。就算调试器能读全部内存能dump全部Flash看到的也只能是经密钥加密后的结果而不是密钥本身。3.3 物理攻击与侧信道防护硬件到底“硬”在哪这个层面是普通项目里最容易忽视、但安全研究里最看重的部分。攻击者如果拿到设备本体可以做功耗分析DPA/SPA、电磁辐射分析、电压/时钟毛刺注入、激光切割芯片内部结构等操作这类统称为侧信道攻击和物理攻击。软件实现加密时CPU的功耗和电磁辐射会随着当前指令和数据变化而波动攻击者采集大量加密波形再结合已知明文统计建模有可能把密钥反推出来。这就是为什么密码学教材里反复强调“常数时间实现”。很多软件库做得好的如mbedTLS的某些版本会尽量做常数时间运算但通用CPU流水线、Cache命中率、分支预测这些硬件行为很难完全控制。硬件密码学引擎在设计时就把侧信道防护纳入考量比如固定执行周期、内部随机掩码、功耗均衡、故障检测。芯片物理层还可能做屏蔽层、防探测走线、主动篡改检测网。这不是说硬件加密绝对安全——任何安全方案都有被实验室级攻击手段破解的可能——但攻击成本会高好几个数量级对绝大多数商业产品来说这个成本已经足以劝退盗版者。4. 怎么选怎么落地实操与避坑4.1 选型决策树别盲目追求“最硬”方案安全设计和性能优化一样第一步永远是定义威胁模型。我见过最典型的问题就是做一个普通物联网传感器数据只是温度湿度也非要上一颗独立安全芯片。这属于把好钢用在了刀背上。反过来做一个几千元的工业控制器固件是整个产品的核心资产结果连Flash读保护都没开这就属于风险敞口太大。我一般会按下面几条线来决策只是为了防止误连接、保住通信链路的保密性设备本身不涉及高价值资产软件AES/ChaCha20加TLS就够了。固件算法有较高商业价值担心被抄板至少要用带AES硬件外设和读保护的MCU配合唯一ID做签名认证。产品需要做配件认证、防伪验证、或者有明确的合规要求直接上独立安全芯片。跑Linux/Android系统且需要Secure Boot选带TrustZone和OTP密钥的SoC配置TEE环境。车规、工业控制等高安全等级场景查一下EVITA/ISO 21434相关要求大概率要上HSM硬件安全模块那不是普通加密外设能替代的。4.2 看似“硬件加密”但实际不安全的三种情况第一种是只有加密引擎、没有安全密钥存储。芯片支持AES加速但密钥明文存在Flash里。这种情况硬件只起了加速作用安全性和软件加密差别不大。第二种是安全功能默认关闭。不少芯片的安全启动、读保护、TrustZone功能默认是开着的或者提供了配置选项之后要主动去固化。很多项目为了方便调试把调试接口一直开着把安全启动机制临时关掉甚至从未打开产品量产时就直接裸奔了。第三种是密钥注入环节出了问题。就算用了ATECC608A这种安全芯片如果产线在写密钥的时候用的是临时编写的上位机脚本没有加密传输、没有脱机工具、参与人员能随意导出密钥文件那再好的硬件也白搭。安全是整条链路的工程不是单点芯片能兜底的。4.3 密钥注入与产线管理容易被忽略的环节密钥注入这块我确实吃过亏。有次替客户做安全认证方案硬件选型、匹配流程都走完了最后卡在产线上安全芯片的密钥需要由服务器生成通过产测软件写入但产线电脑本身就联网还装了各种不明软件密钥文件在电脑上放了很久。这等于直接把保险柜密码贴在了柜子上。正确的做法一般是这样密钥生成和存储放在离线环境或者专用HSM里产线通过加密协议把“待烧录的密钥密文”下发烧录工具只支持写入不支持读取烧完之后立即做一次校验并清除本地缓存。再进一步按批次拆封密钥每台设备拿到不同的密钥避免一个泄露全盘皆输。另外烧录环节要记录日志查审计数量要对得上芯片出库数量防止多余的、带密钥的芯片流向不可控渠道。5. 常见问题与排查技巧实录5.1 常见问题快查表现象可能原因排查与解决思路调用硬件AES外设后程序跑飞未使能AHB/APB总线时钟或未正确复位检查RCC寄存器确认外设时钟开启在初始化时先复位模块再配置加密结果和软件加密不一致字节序/数据对齐方式不同或密钥字节序处理错误对比两边的密钥存储顺序大端/小端确认AES模式ECB/CBC/CTR和填充方式一致使用ATECC608A等安全芯片通信失败I2C地址、总线速度、延时参数不对看数据手册的时序要求I2C频率别拉太高确认唤醒序列是否正确开了读保护后调试器连不上MCURDP级别设置过高或设置后未全片擦除需要全片擦除才能降级量产前先确认调试策略建议做成可配置开关安全启动配置后固件无法启动密钥烧录顺序或签名工具链版本不匹配先烧key再烧签名固件确认校验证书和烧录密钥ID对应保留一级回退bootloader实测硬件加密功耗不降反升加密外设时钟一直全速跑没有门控只在需要时打开加密外设时钟完成后立刻关闭尽量用DMA减少唤醒次数5.2 几个真实调试经验第一个经验来自STM32系列。之前用STM32L4的AES外设做GCM模式数据加密一开始怎么都不通过最后发现是数据寄存器是32位的而我的数据缓冲区是按字节对齐的。把输入数据改成uint32_t数组、按手册要求做字节序翻转之后问题就消失了。所以遇到硬件加密结果不对先别怀疑芯片优先检查数据格式、密钥格式和算法模式。第二个经验是ESP32上的Secure Boot和Flash加密配合。默认情况下ESP32的Flash加密只加密代码段如果应用层在NVS非易失存储里存了敏感数据那部分是不受保护的。我当时在NVS里放了通信用的预共享密钥后来才意识到Fortune-flash backup或者攻击者直接读出NVS分区密钥照样泄露。这类问题不是硬件不支持是“硬件能力”和“使用方式”没有对齐。第三个经验是调试独立安全芯片的时候特别容易被外部的上拉电阻坑到。I2C总线上ATECC608A需要在地址脚上正确处理上下拉有的开发板上默认上了拉导致芯片地址漂移怎么都枚举不到设备。花了一个下午查I2C波形才发现的。所以硬件安全方案出问题时先把物理层和电源时序排干净别一头扎进密码学细节里。还有个提醒不少硬件加密模块在低功耗模式下是不工作的。你在Sleep模式下调一次签名请求芯片可能一直等不到回应造成了莫名的唤醒电流。产品设计时一定要把“进入低功耗前关掉加密外设、唤醒后重新初始化”这个流程写清楚。选型的时候也别忽略了工具链的成本。独立安全芯片的配置工具、密钥管理软件、产线烧录方案这些不是免费送的。ATECC608A有配套的CryptoAuthLib看起来还不错但真要集成到自己的安全启动和通信协议里需要花时间读API文档和参考设计。ROI要算清楚别安全等级上去了开发周期也跟着上去了。我自己的习惯是产品定义阶段先把“我要防谁”写清楚再根据威胁选择安全等级最后才去翻芯片选型表。方案落地时一定会专门留一块时间验证密钥注入流程和产线工具链因为这块的隐藏问题往往比算法代码本身多得多。