3、固件签名工具链:OpenSSL工具安装、密钥对生成、证书格式(PEM/DER)

好,咱们进入正题。这一章聊的是固件签名的“吃饭家伙”——OpenSSL。说白了,它就是一把瑞士军刀,能帮你搞定密钥生成、证书管理、签名验签这些脏活累活。我个人习惯把这一套流程叫做“签名工具链”,因为从安装到生成密钥,再到理解证书格式,每一步都环环相扣。

核心知识点速览:

  • OpenSSL 的安装与验证
  • RSA/ECC 密钥对生成
  • PEM 与 DER 格式的区别与转换
  • 自签名证书的创建
固件签名工具链核心流程 OpenSSL 安装 密钥对生成 证书格式转换 Linux / macOS / Windows RSA 2048 / ECC P-256 PEM ↔ DER 互转 最终产出:签名固件 + 公钥证书

3.1 OpenSSL 安装——别小看这一步

你可能觉得安装工具没什么好讲的,但我在项目中遇到过好几次因为版本不对导致签名验证失败的坑。嗯,这里要注意:嵌入式环境对 OpenSSL 版本很敏感,尤其是 1.1.1 和 3.x 之间有些 API 不兼容。

我个人建议用 1.1.1 系列,稳定、文档多。如果你在 Linux 上干活,直接:

# Ubuntu / Debian
sudo apt-get install openssl

# CentOS / RHEL
sudo yum install openssl

# macOS (用 Homebrew)
brew install openssl

装完之后,验证一下:

openssl version
# 输出类似:OpenSSL 1.1.1w  11 Sep 2023

小提示:Windows 用户可以去官网下载预编译包,或者用 WSL。我个人更推荐 WSL,因为命令行体验和 Linux 一致,省去很多麻烦。

3.2 密钥对生成——RSA 还是 ECC?

好,工具装好了,咱们来生成密钥对。这里有个经典问题:用 RSA 还是 ECC?

我直接说结论:新项目优先选 ECC P-256。为什么?密钥更短、性能更好、安全性相当。但如果你要兼容老硬件,RSA 2048 还是主流。

先看 RSA 的生成方式:

# 生成 RSA 私钥(2048位)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private_key.pem

# 从私钥提取公钥
openssl pkey -in private_key.pem -pubout -out public_key.pem

再看 ECC 的:

# 生成 ECC 私钥(P-256 曲线)
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ecdsa_private.pem

# 提取公钥
openssl pkey -in ecdsa_private.pem -pubout -out ecdsa_public.pem

警告:私钥文件一定要保护好!我曾经见过有人把私钥直接提交到 Git 仓库里……那场面,简直是灾难。建议用 chmod 600 限制权限,并考虑硬件安全模块(HSM)存储。

3.3 证书格式:PEM vs DER——到底有什么区别?

你可能会问:为什么要有两种格式?说白了,PEM 是给人看的,DER 是给机器吃的。

特性 PEM DER
编码方式 Base64 文本 二进制
可读性 高(可用记事本打开) 低(乱码)
文件大小 约大 30% 更紧凑
典型用途 OpenSSL 工具、证书分发 嵌入式固件、Java 环境
文件头 -----BEGIN CERTIFICATE----- 无文本头

PEM 格式长这样:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...
-----END PRIVATE KEY-----

而 DER 就是一堆二进制,你用 xxd 看会看到十六进制数据。

转换也很简单:

# PEM → DER
openssl x509 -in cert.pem -outform DER -out cert.der

# DER → PEM
openssl x509 -in cert.der -inform DER -out cert.pem

实战经验:我在做一款 IoT 设备时,发现 bootloader 只认 DER 格式的证书。当时我拿着 PEM 文件折腾了半天,最后发现加个 -outform DER 参数就搞定了。你想想看,这种小细节卡住你半天,多冤啊。

3.4 自签名证书——快速搭建信任链

在开发阶段,我们通常用自签名证书来模拟生产环境。别觉得它“不正规”,其实流程和 CA 签发的证书一模一样。

# 生成自签名证书(有效期10年)
openssl req -x509 -newkey rsa:2048 -keyout ca_key.pem -out ca_cert.pem \
  -days 3650 -nodes -subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=MyRootCA"

参数说明:

  • -x509:直接输出证书,而不是证书签名请求(CSR)
  • -nodes:不加密私钥(开发环境方便,生产环境别用)
  • -subj:主题信息,按需填写

避坑指南:我曾经把 -days 设成 36500(100年),结果某些 bootloader 因为时间戳溢出直接拒绝加载。所以建议有效期别超过 20 年,10 年是个安全值。

3.5 验证你的工具链——签名与验签

密钥和证书都准备好了,咱们来走一遍完整的签名流程。这步能帮你确认工具链没装错。

# 1. 计算固件哈希
openssl dgst -sha256 -binary firmware.bin > firmware.hash

# 2. 用私钥签名
openssl pkeyutl -sign -inkey private_key.pem -in firmware.hash -out firmware.sig

# 3. 用公钥验签
openssl pkeyutl -verify -pubin -inkey public_key.pem -in firmware.hash -sigfile firmware.sig

如果验签输出 Signature Verified Successfully,恭喜你,工具链跑通了!

注意:实际产品中,签名算法通常会用 openssl dgst -sha256 -sign 一步完成哈希+签名,但分开做能让你更清楚每一步在干什么。我个人调试时喜欢分开做,方便定位问题。

好,这一章的内容就到这里。工具链搭好了,密钥生成了,格式也搞明白了——接下来你就可以放心地去给固件签名了。记住,密钥安全是第一位的,别让私钥裸奔。

可可精品资料库