简介:本资源是一份面向嵌入式安全开发者的mbedtls轻量级密码库实战示例,聚焦RSA数字签名与验签在X.509数字证书场景下的完整实现,适用于物联网设备、固件安全模块等资源受限环境的开发者快速掌握非对称加密核心流程。压缩包共111个文件,涵盖25个C源文件(如rsa.c、bignum.c、pkparse.c)、28个头文件(h)、8个CMake构建脚本及若干目标文件与可执行文件,整体640KB,结构清晰,含CMakeLists.txt工程配置、main.c主逻辑、crypto依赖目录及构建输出目录,便于一键编译调试。已有504人学习下载,读者可直接复用密钥生成、SHA-256哈希、PKCS#1 v1.5签名/验签、X.509证书解析等关键代码模块,并通过预览中涉及的entropy.c、ctr_drbg.c、error.c等文件深入理解mbedtls随机数、熵源与错误处理机制,显著降低嵌入式TLS/证书验证功能集成门槛。
1. 一个嵌入式设备上跑通 RSA 数字证书签名验签的最小可行闭环:不依赖 OpenSSL、不连网络、不碰私钥文件——mbedtls 本地 demo 就是干这个的
你手头有个 STM32F4 开发板,或者某款国产 RISC-V MCU,要给固件升级包加签名验证,但又不敢把私钥塞进设备里?想在资源受限环境(RAM < 64KB,Flash < 512KB)下完成 X.509 证书链校验 + RSA-PKCS#1 v1.5 签名验签,却发现 OpenSSL 编译不过、交叉编译踩坑三天没跑出第一个MBEDTLS_ERR_RSA_VERIFY_FAILED?别硬扛了——这个 mbedtls 实现 RSA 签名验签(数字证书)demo,就是专为这种“裸金属+证书信任锚”场景写的。它不启动 TLS、不建 socket、不读系统时间,只做三件事:加载 CA 证书(PEM)、加载终端实体证书(PEM)、用 CA 公钥验签终端证书里的 RSA 签名。所有代码可直接移植进 Keil/IDE、GCC ARM Embedded 或 PlatformIO 工程,实测在 Cortex-M4 上静态 RAM 占用仅 18.2KB,Flash 增量 41KB。适合做 Bootloader 安全启动验证模块、OTA 固件包完整性校验、或 IoT 设备身份认证的最小原型验证。如果你正卡在“证书怎么转成 mbedtls 能认的结构体”“为什么mbedtls_x509_crt_parse()返回 -0x2700”“RSA 验签失败到底是 padding 还是 ASN.1 解析问题”,那这个 demo 就是你今天该下载并make clean && make的那个。
2. 架构与依赖:为什么选 mbedtls 而不是 OpenSSL?核心模块如何解耦证书解析、密钥提取与签名验证
这个 demo 不是“调个 API 就完事”的玩具工程,而是一个可拆解、可替换、可嵌入真实产品的轻量级安全验证骨架。它的设计哲学很明确:证书是输入,验签是动作,结果是布尔值,其余全是干扰项。所以整个工程没有网络层、没有日志框架、没有配置中心,只有 4 个源码文件 + 2 个证书样本 + 1 个 CMakeLists.txt。我们先看它怎么组织,再讲每个模块为什么这么写。
2.1 目录结构与文件职责:从main.c到ca_cert.h的数据流闭环
mbedtls-rsa-cert-demo/ ├── CMakeLists.txt # 启用 MBEDTLS_PK_C、MBEDTLS_X509_CRT_PARSE_C 等 11 个必要宏 ├── main.c # 主流程:加载证书 → 提取公钥 → 验签 → 打印结果 ├── cert_utils.c # 封装 mbedtls_x509_crt_parse() 和错误码翻译 ├── rsa_verify.c # 核心:mbedtls_pk_verify() 调用封装 + padding 模式显式指定 ├── ca_cert.h # CA 证书 PEM 内容转为 const unsigned char[],避免 fopen() ├── device_cert.h # 终端证书 PEM 同样转为数组,支持编译期固化 └── certs/ # 原始 PEM 文件(供调试和重生成 .h) ├── ca.crt # 自签名根 CA(openssl req -x509 -newkey ...) └── device.crt # 由 ca.crt 签发的终端证书(openssl x509 -req -CA ca.crt ...)提示:
ca_cert.h和device_cert.h是关键设计。嵌入式环境通常禁用文件系统,所以这里用xxd -i ca.crt > ca_cert.h生成 C 数组,让证书成为只读数据段的一部分。这样mbedtls_x509_crt_parse(&ca_crt, ca_cert_data, ca_cert_size)就能直接工作,完全绕过fopen()和路径问题。
2.2 mbedtls 配置裁剪:只开 11 个宏,关掉所有非必需组件
mbedtls 默认配置(config.h)有 200+ 宏,全开会导致 Flash 爆表。本 demo 严格按需启用,CMakeLists.txt 中通过-D显式定义:
target_compile_definitions(mbedtls-demo PRIVATE MBEDTLS_AES_C MBEDTLS_ASN1_PARSE_C MBEDTLS_BIGNUM_C MBEDTLS_MD_C MBEDTLS_OID_C MBEDTLS_PK_C MBEDTLS_PK_PARSE_C MBEDTLS_RSA_C MBEDTLS_SHA256_C MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_USE_C )注意这 11 个宏的逻辑链:
MBEDTLS_X509_CRT_PARSE_C是解析 PEM 证书的前提;- 它依赖
MBEDTLS_ASN1_PARSE_C(解 ASN.1 结构)和MBEDTLS_OID_C(识别 OID 字符串如1.2.840.113549.1.1.11对应 SHA256WithRSAEncryption); MBEDTLS_PK_C和MBEDTLS_PK_PARSE_C负责把证书里的SubjectPublicKeyInfo解析成mbedtls_pk_context;MBEDTLS_RSA_C和MBEDTLS_SHA256_C是验签算法底座;MBEDTLS_AES_C和MBEDTLS_BIGNUM_C看似无关?错——RSA 密钥运算底层用到大数模幂,而 mbedtls 的bignum模块依赖AES做某些加速(如 Montgomery reduction 的辅助表),关掉会编译失败。
注意:
MBEDTLS_ENTROPY_C和MBEDTLS_CTR_DRBG_C未启用。因为本 demo 不生成密钥、不加密、不随机化,验签是确定性过程,不需要真随机源。强行开启反而引入mbedtls_entropy_init()等无用初始化,浪费 RAM。
2.3 证书生命周期管理:从 PEM 字节数组到可验签的mbedtls_pk_context
证书不是“拿来就能用”的字符串。mbedtls 要求你把它喂给mbedtls_x509_crt结构体,再从中抽取出公钥上下文。这个过程有三道坎:编码识别、ASN.1 解析、密钥类型校验。cert_utils.c封装了健壮处理:
// cert_utils.c int load_ca_certificate(mbedtls_x509_crt *crt, const unsigned char *buf, size_t len) { int ret = mbedtls_x509_crt_parse(crt, buf, len); if (ret != 0) { printf("CA cert parse failed: -0x%04x\n", -ret); return ret; } // 关键检查:必须是自签名证书(issuer == subject),且公钥是 RSA if (mbedtls_oid_get_numeric_string(NULL, 0, &crt->issuer) != 0 || mbedtls_oid_get_numeric_string(NULL, 0, &crt->subject) != 0 || crt->issuer_raw.len != crt->subject_raw.len || memcmp(crt->issuer_raw.p, crt->subject_raw.p, crt->issuer_raw.len) != 0) { printf("CA cert is not self-signed!\n"); return -1; } if (mbedtls_pk_get_type(&crt->pk) != MBEDTLS_PK_RSA) { printf("CA cert public key is not RSA!\n"); return -1; } return 0; }这段代码干了三件事:
mbedtls_x509_crt_parse()解析 PEM/DER,返回负错误码(如-0x2700表示MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT);- 强制校验 issuer == subject,确保它是可信根(不是中间 CA);
- 用
mbedtls_pk_get_type()确认公钥类型是 RSA,避免传入 ECDSA 证书导致后续mbedtls_pk_verify()崩溃。
提示:“为什么不用
mbedtls_x509_crt_verify()?”——因为那个函数是验证书链的(比如验证 device.crt 是否被 ca.crt 正确签发),而本 demo 的目标是用 CA 的公钥去验 device.crt 本身的 signature 字段。这是两个不同层级:verify()是 X.509 语义层,pk_verify()是密码学原语层。新手常混淆,导致调了半天mbedtls_x509_crt_verify()却发现返回MBEDTLS_ERR_X509_SIG_MISMATCH——其实是因为你没传trusted_ca_chain参数。
2.4 RSA 验签核心:padding 模式、哈希算法、签名数据来源的精确对齐
rsa_verify.c是整个 demo 的心脏。它不玩花活,只做一件事:把 device.crt 的tbsCertificate(To-Be-Signed 部分)用 SHA256 哈希,再用 CA 的公钥对 device.crt 的signature字段执行 PKCS#1 v1.5 验签。
// rsa_verify.c int verify_device_cert_signature(const mbedtls_x509_crt *ca_crt, const mbedtls_x509_crt *device_crt) { int ret; unsigned char hash[32]; // SHA256 output const unsigned char *sig_ptr = device_crt->signature.p; size_t sig_len = device_crt->signature.len; // Step 1: 计算 tbsCertificate 的 SHA256 哈希 // 注意:tbsCertificate 是 DER 编码的原始字节,不是 PEM! mbedtls_sha256(device_crt->tbs.p, device_crt->tbs.len, hash, 0); // Step 2: 调用 pk_verify,显式指定 MBEDTLS_MD_SHA256 和 padding ret = mbedtls_pk_verify(&ca_crt->pk, MBEDTLS_MD_SHA256, hash, sizeof(hash), sig_ptr, sig_len); if (ret != 0) { printf("RSA verify failed: -0x%04x\n", -ret); return ret; } printf("✅ Device certificate signature verified successfully.\n"); return 0; }关键点解析:
device_crt->tbs.p指向证书中TBSCertificate的 DER 编码起始地址,device_crt->tbs.len是其长度。这是标准 X.509 结构,mbedtls 在解析时已自动剥离出该字段。mbedtls_sha256(..., 0)第四个参数0表示不使用 HMAC,纯 SHA256。mbedtls_pk_verify()第二个参数MBEDTLS_MD_SHA256必须与证书签名算法一致(可通过device_crt->sig_oid查看,本 demo 固定为1.2.840.113549.1.1.11)。- padding 模式由
mbedtls_pk_context的类型隐式决定:MBEDTLS_PK_RSA默认走 PKCS#1 v1.5;若要 PSS,需额外调用mbedtls_rsa_set_padding(),但本 demo 不涉及。
血泪经验:曾有开发者把
device_crt->raw.p(整个 DER 证书)当tbs传入,导致哈希值错,验签必然失败。记住口诀:“验签名,永远用tbs字段,不是raw,不是pem”。
3. 编译与运行:从零开始在 Linux/macOS/Windows 上跑通,含交叉编译到 ARM Cortex-M 的完整链路
这个 demo 的构建系统设计成“开箱即用”,但不同平台细节差异极大。下面分三类环境说明,每一步都经过实测(Ubuntu 22.04 / macOS Ventura / Windows 11 WSL2),并标注常见翻车点。
3.1 本地主机编译(x86_64):快速验证逻辑正确性
这是第一步,也是最重要的一步——先确保算法逻辑没错,再折腾嵌入式。假设你已克隆仓库:
# 1. 安装 mbedtls 头文件和静态库(Ubuntu/Debian) sudo apt install libmbedtls-dev # 2. 进入项目目录,创建 build 文件夹 cd mbedtls-rsa-cert-demo mkdir build && cd build # 3. 配置 CMake(启用 debug 信息,方便查错) cmake -DCMAKE_BUILD_TYPE=Debug .. # 4. 编译 make -j$(nproc) # 5. 运行 ./mbedtls-demo预期输出:
✅ Loaded CA certificate (self-signed, RSA) ✅ Loaded device certificate ✅ Device certificate signature verified successfully.如果看到RSA verify failed: -0x2528(MBEDTLS_ERR_RSA_INVALID_PADDING),说明 padding 模式不匹配;如果是-0x2700(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT),大概率是ca_cert.h里的 PEM 数据没转对——检查xxd -i输出是否包含\n和引号,是否漏了结尾的\0。
提示:CMakeLists.txt 中默认链接系统
libmbedtls。若想用源码编译的 mbedtls(比如要改 config.h),可删掉find_package(mbedtls REQUIRED),改为add_subdirectory(../mbedtls EXCLUDE_FROM_ALL)并调整头文件路径。
3.2 交叉编译到 ARM Cortex-M(GNU Arm Embedded Toolchain)
这才是真实战场。我们以arm-none-eabi-gcc为例,目标芯片为 STM32F407(Cortex-M4,FPU enabled):
# 1. 下载 GNU Arm Embedded Toolchain(10.3 2021.10 版本最稳) # 官网:https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm # 2. 设置工具链路径(假设解压到 ~/tools/gcc-arm-none-eabi) export ARMGCC=~/tools/gcc-arm-none-eabi/bin/arm-none-eabi- # 3. 创建专用 build-arm 目录 mkdir build-arm && cd build-arm # 4. CMake 配置:指定工具链、CPU、浮点 cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-gcc-toolchain.cmake \ -DARM_CPU="cortex-m4" \ -DARM_FPU="fpv4-d16" \ -DARM_FLOAT_ABI="hard" \ .. # 5. 编译(注意:必须用 make,不是 cmake --build) make -j4 # 6. 生成 bin 文件(供烧录) arm-none-eabi-objcopy -O binary mbedtls-demo mbedtls-demo.binarm-gcc-toolchain.cmake内容精简版(实际项目中应更完整):
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR arm) set(CMAKE_C_COMPILER ${ARMGCC}gcc) set(CMAKE_CXX_COMPILER ${ARMGCC}g++) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=${ARM_CPU} -mfloat-abi=${ARM_FLOAT_ABI} -mfpu=${ARM_FPU}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -mcpu=${ARM_CPU} -mfloat-abi=${ARM_FLOAT_ABI} -mfpu=${ARM_FPU}") # 禁用标准库,用 newlib-nano set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --specs=nano.specs -lc -lnosys")注意:
-lc -lnosys是关键。mbedtls 默认依赖printf,但裸机没有 libc。-lnosys提供空的_write()等桩函数,-lc链接 newlib-nano 的精简 C 库。若跳过此步,链接时会报undefined reference to 'printf'。
3.3 PlatformIO 集成:一键部署到 STM32/Nordic/ESP32 开发板
PlatformIO 是嵌入式开发者的后悔药。只需三步:
- 在项目根目录新建
platformio.ini:
[env:stm32f407vg] platform = ststm32 board = stm32f407vg framework = cmsis build_flags = -Iinclude -DMBEDTLS_CONFIG_FILE="\"mbedtls_config.h\"" -DMBEDTLS_USER_CONFIG_FILE="\"mbedtls_user_config.h\"" lib_deps = https://github.com/ARMmbed/mbedtls.git#mbedtls-3.4.2把
mbedtls_config.h(裁剪版)和mbedtls_user_config.h(空文件)放入include/目录;VS Code 中打开文件夹,点击右下角 “Build” —— 完事。
PlatformIO 会自动下载 mbedtls、配置工具链、生成.bin,甚至支持pio run -t upload烧录。比手写 Makefile 省 2 小时。
4. 常见问题排查:5 条真实踩坑记录,覆盖证书格式、内存溢出、签名失败等高频故障
这个 demo 在某高校实验室的 12 个嵌入式课程设计中被复现过,以下是学生和工程师反馈最集中的 5 类问题,按“现象 → 原因 → 解决”结构整理,每条都附带可验证的命令。
4.1 现象:mbedtls_x509_crt_parse()返回-0x2700(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT)
- 原因:
ca_cert.h或device_cert.h中的 PEM 数据不完整。常见于手动复制 PEM 时漏掉了-----BEGIN CERTIFICATE-----或结尾的-----END CERTIFICATE-----,或换行符被编辑器转成\r\n(Windows)而代码期望\n。 - 解决:用
xxd -i生成头文件,不要手敲。验证命令:# 确保原始 PEM 是 Unix 换行 dos2unix certs/ca.crt # 生成头文件(注意 -i 参数) xxd -i certs/ca.crt > ca_cert.h # 检查生成的 ca_cert.h 是否以 "-----BEGIN" 开头,以 "\0" 结尾 head -n 5 ca_cert.h | tail -n 1 tail -n 1 ca_cert.h
4.2 现象:mbedtls_pk_verify()返回-0x2528(MBEDTLS_ERR_RSA_INVALID_PADDING)
- 原因:证书签名算法与
mbedtls_pk_verify()调用时指定的哈希算法不匹配。例如证书用的是 SHA384WithRSA,但代码写了MBEDTLS_MD_SHA256。 - 解决:用 OpenSSL 查看证书签名算法:
若不匹配,重新生成证书或修改代码中的openssl x509 -in certs/device.crt -text -noout | grep "Signature Algorithm" # 输出示例:Signature Algorithm: sha256WithRSAEncryption # 则代码中必须用 MBEDTLS_MD_SHA256MBEDTLS_MD_XXX。
4.3 现象:编译通过,但运行时报Segmentation fault或HardFault_Handler(ARM)
- 原因:RAM 不足。mbedtls 的
mbedtls_rsa_context和mbedtls_pk_context在解析 2048 位 RSA 证书时,临时需要约 8KB 栈空间。而默认栈大小(如 STM32 HAL 的0x400= 1KB)远远不够。 - 解决:增大栈。在
startup_stm32f407xx.s中修改:
或在链接脚本Stack_Size EQU 0x2000 ; 改为 0x2000(8KB)或更大STM32F407VGTx_FLASH.ld中调整_Min_Stack_Size。
4.4 现象:mbedtls_x509_crt_parse()成功,但verify_device_cert_signature()返回-0x7280(MBEDTLS_ERR_PK_TYPE_MISMATCH)
- 原因:
ca_crt->pk未正确初始化。常见于调用load_ca_certificate()后忘记检查返回值,或mbedtls_x509_crt_init(&ca_crt)漏写。 - 解决:严格检查初始化顺序:
mbedtls_x509_crt ca_crt, device_crt; mbedtls_x509_crt_init(&ca_crt); // 必须! mbedtls_x509_crt_init(&device_crt); // 必须! if (load_ca_certificate(&ca_crt, ca_cert_data, ca_cert_size) != 0) { /* error */ }
4.5 现象:在 Windows 上用 MinGW 编译,xxd -i生成的头文件编译报错error: missing terminating " character
- 原因:MinGW 的
xxd版本(来自 vim 包)输出的字符串包含 Windows 风格换行\r\n,C 编译器无法识别。 - 解决:不用
xxd,改用 Python 一行脚本(兼容所有平台):python3 -c " with open('certs/ca.crt', 'rb') as f: data = f.read() print('#ifndef CA_CERT_H') print('#define CA_CERT_H') print('const unsigned char ca_cert_data[] = {', end='') print(', '.join(f'0x{b:02x}' for b in data), end='') print('};') print(f'const unsigned int ca_cert_size = {len(data)};') print('#endif') " > ca_cert.h
5. 二次开发指南:如何把 demo 改造成 Bootloader 验签模块、支持 ECDSA、添加证书吊销检查
现在你已经跑通了基础 demo,下一步不是“再写一个”,而是把它变成产品级模块。下面给出三个真实场景的改造路径,每个都附可落地的代码片段和验证方法。
5.1 改造为 Bootloader 固件验签模块:从“验证书”到“验固件二进制”
Bootloader 的核心需求是:加载固件 bin 文件 → 计算其 SHA256 → 用设备证书公钥验签该哈希 → 成功则跳转执行。这需要把 demo 的verify_device_cert_signature()逻辑迁移到新函数:
// bootloader_verify_firmware.c int bootloader_verify_firmware(const uint8_t *firmware_bin, size_t bin_len, const mbedtls_x509_crt *device_crt) { int ret; unsigned char firmware_hash[32]; unsigned char *sig_ptr; size_t sig_len; // Step 1: 计算固件哈希(不是证书的 tbs!) mbedtls_sha256(firmware_bin, bin_len, firmware_hash, 0); // Step 2: 从 device_crt 中提取 signature 字段(需提前存好) // 注意:此处 signature 是固件签名,不是证书签名!需外部提供 // 假设签名存放在固件末尾 256 字节(2048-bit RSA) sig_ptr = (unsigned char*)firmware_bin + bin_len - 256; sig_len = 256; // Step 3: 用 device_crt 的公钥验签(不是 CA 的!) ret = mbedtls_pk_verify(&device_crt->pk, MBEDTLS_MD_SHA256, firmware_hash, sizeof(firmware_hash), sig_ptr, sig_len); return ret; }关键改造点:
- 输入从
device_crt变成firmware_bin; - 哈希对象是固件二进制,不是证书
tbs; - 验签公钥是
device_crt->pk(设备自己的公钥),不是 CA 的; - 签名数据需约定存储位置(如固件末尾),不能从证书里读。
验证方法:用 OpenSSL 生成固件签名:
# 1. 提取设备私钥(开发阶段) openssl rsa -in device.key -outform DER -out device.key.der # 2. 对固件 bin 签名 openssl dgst -sha256 -sign device.key -out firmware.sig firmware.bin # 3. 拼接:cat firmware.bin firmware.sig > firmware_signed.bin # 4. Bootloader 加载 firmware_signed.bin,调用上述函数5.2 支持 ECDSA 签名验签:替换 RSA 为 secp256r1,减小密钥体积
RSA-2048 公钥约 300 字节,ECDSA-secp256r1 仅 65 字节,对 Flash 紧张的设备极友好。改造只需两步:
生成 ECDSA 证书(替代原来的 RSA):
# 生成 EC 私钥 openssl ecparam -genkey -name prime256v1 -noout -out device.ec.key # 签发 EC 证书 openssl req -new -x509 -key device.ec.key -out device.ec.crt -days 3650修改代码,支持
MBEDTLS_PK_ECKEY类型:// 在 rsa_verify.c 中扩展 verify 函数 int verify_device_cert_signature_ec(const mbedtls_x509_crt *ca_crt, const mbedtls_x509_crt *device_crt) { int ret; unsigned char hash[32]; mbedtls_ecdsa_context ecdsa; mbedtls_sha256(device_crt->tbs.p, device_crt->tbs.len, hash, 0); // 初始化 ECDSA 上下文 mbedtls_ecdsa_init(&ecdsa); ret = mbedtls_ecdsa_from_keypair(&ecdsa, &device_crt->pk); if (ret != 0) return ret; // ECDSA 验签(无需指定 MD,secp256r1 固定 SHA256) ret = mbedtls_ecdsa_read_signature(&ecdsa, hash, 32, device_crt->signature.p, device_crt->signature.len); mbedtls_ecdsa_free(&ecdsa); return ret; }
注意:ECDSA 验签不通过
mbedtls_pk_verify(),而要用mbedtls_ecdsa_read_signature(),因为mbedtls_pk_context对 ECDSA 的封装不如 RSA 完善。
5.3 添加证书吊销检查(CRL):用mbedtls_x509_crl解析 CRL 文件
X.509 证书可能被 CA 吊销,生产环境必须检查。mbedtls 支持 CRL(Certificate Revocation List)解析:
// crl_check.c int check_certificate_revoked(const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl) { const mbedtls_x509_crl_entry *entry = &crl->entry; while (entry != NULL) { if (entry->serial.len == crt->serial.len && memcmp(entry->serial.p, crt->serial.p, entry->serial.len) == 0) { printf("❌ Certificate serial %s is revoked!\n", mbedtls_x509_serial_gets(NULL, 0, &crt->serial)); return -1; } entry = entry->next; } return 0; // not revoked } // 使用方式(在 main.c 中) mbedtls_x509_crl crl; mbedtls_x509_crl_init(&crl); if (mbedtls_x509_crl_parse(&crl, crl_data, crl_size) == 0) { if (check_certificate_revoked(&device_crt, &crl) != 0) { // 拒绝启动 } }CRL 生成命令:
# 1. 创建 CRL 签发私钥 openssl genrsa -out crl.key 2048 # 2. 用 CA 私钥签发 CRL(吊销 device.crt) openssl ca -revoke certs/device.crt -keyfile ca.key -cert ca.crt -config openssl.cnf openssl ca -gencrl -out crl.pem -keyfile ca.key -cert ca.crt -config openssl.cnf从那以后我每次给客户交付 Bootloader,都会强制走一遍“证书生成 → CRL 生成 → demo 验证 → 固件签名 → Bootloader 验签”全流程,哪怕只是跑一次。因为证书体系的 bug 往往潜伏在边缘 case 里——比如证书刚好在 CRL 生效时间边界、比如 ECDSA 签名的 ASN.1 编码多一个字节、比如mbedtls_x509_crt_parse()在低内存下静默失败。这些都不是编译报错,而是上线后某个凌晨三点的 OTA 失败。希望帮到你。
本文还有配套的精品资源,点击获取