第4章 密钥存储:从文件到硬件,你选对了吗?

密钥存储这件事,我见过太多项目栽跟头了。有人直接把私钥写在配置文件里,有人存数据库但不加密,还有人把HSM当摆设。其实选对存储方式,比你想象中更重要。

这一章我们聊聊常见的密钥存储手段——文件、数据库、HSM、以及各种容器格式。你可能会问:不就是存个密钥吗,至于这么讲究?嗯,我们一个个看。

文件存储:最方便,也最危险

说白了一句话:把密钥当普通文件存。开发阶段图省事,很多人这么干。但我建议你至少做到两点:

  • 密钥文件权限必须严格(Linux下 chmod 600)
  • 文件内容必须加密——明文存私钥,跟把密码贴电脑上没区别

我在项目中遇到过一个小团队,他们把SM2私钥直接写进 config.json,还上传到Git仓库。结果呢?被扫描工具发现,当天就被安全团队要求重做整个密钥体系。避坑指南:明文密钥永远不要进版本控制。

数据库存储:集中管理,但要看住钥匙

用数据库统一管理密钥,适合多应用共享的场景。常见的做法是建一张密钥表,存ID、算法、密钥密文、有效期等。

但有个关键点:密钥本身的加密密钥(KEK)放哪? 你想想看,如果KEK也存同一个数据库,那加密就没意义了。我自己的习惯是:KEK来源于外部——环境变量、HSM或者专门的密钥管理服务。

存储方式优点缺点
明文文件简单直接易泄露、难轮换
加密文件(如PKCS#8)标准、可传输需要额外保护口令
数据库存储集中管理、审计方便KEK保护是关键
HSM存储硬件隔离、防物理攻击成本高、性能有损耗

HSM存储:银行级的安全选择

HSM全称硬件安全模块,说白了就是一个专门干「密钥运算」的黑盒子。密钥生成、签名、加密全在硬件里完成,私钥永远不会离开设备。

曾经有个金融客户问我:HSM这么贵,值吗?我反问他:「你的私钥值多少钱?」如果泄露可能导致上千万损失,那HSM就是保险。

国密场景下,目前主流的HSM都支持SM2/SM3/SM4。对接时要注意两点:

  • HSM厂商的PKCS#11接口实现是否完整
  • 密钥备份方案——HSM坏了,你的密钥能恢复吗?

密钥容器格式:PKCS#8、PEM、DER

这几个格式你可能经常碰见。我帮你理清区别:

  • PKCS#8:标准私钥封装格式,支持加密(用口令保护)。国密SM2私钥建议用这个格式导出。
  • PEM:文本格式,Base64编码,带 -----BEGIN ...----- 头尾。其实就是把DER用Base64包裹一层。
  • DER:二进制格式,文件小,但不可读。

实际项目中,我通常用PKCS#8加密存储私钥,扩散给其他服务时用PEM格式传输。举个例子:

# 导出SM2私钥为加密PKCS#8(PEM格式)
gmssl sm2 -ec_paramgen_curve:sm2p256v1 -genkey -out sm2.key.pem
gmssl pkcs8 -topk8 -in sm2.key.pem -out sm2.enc.pem -passout pass:yourpass

# 查看私钥信息
gmssl pkcs8 -in sm2.enc.pem -passin pass:yourpass -info

提示: 如果你用OpenSSL 3.x,注意国密曲线名称是 SM2 而不是 sm2p256v1。不同版本差异很大,建议先 openssl ecparam -list_curves 确认支持情况。

本地安全存储方案:实战中的选择

本地安全存储,核心思路就是「把密钥藏好」。根据平台不同,方案也不同:

  • Linux:使用密钥环(keyutils)、Trousers或直接依赖文件权限 + dm-crypt
  • Windows:DPAPI(Data Protection API)加密密钥后存注册表或文件
  • Android/iOS:使用KeyStore/Keychain,由TEE保护

我曾经被一个嵌入式项目问住:没有操作系统、没有TPM,怎么存SM2私钥?最后方案是:把密钥拆成两份(门限签名?来不及改架构了),一份固化在Boot ROM,一份存外部加密Flash,上电后合成。

警告: 不要自己发明密钥衍生算法!使用标准KDF(如PBKDF2、scrypt)从口令导出加密密钥。我们见过有人自己写循环取模,结果密钥空间只有2^24,暴力破解几分钟就出来了。

好了,这一章的知识点就这些。下面这张图可以帮你快速回忆几种存储方式的关系:

密钥存储方式选择决策图 密钥存储 文件存储 权限+加密,防Git泄露 数据库存储 KEK外部化,审计日志 HSM存储 硬件隔离,PKCS#11接口 本地安全存储 DPAPI / KeyStore / Keychain 容器格式 PKCS#8/PEM/DER 决策要点: - 开发测试:加密文件 + 密钥环 / 环境变量 - 生产环境:HSM(高安全)或数据库+KEK外部化(中安全)

总结一下:没有银弹。你的场景、预算、合规要求决定了选择。但有一条底线——绝不要明文存私钥,无论用哪种方式。