ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32H5 DA调试认证证书链命令行批量生成与产线自动化实践

STM32H5 DA调试认证证书链命令行批量生成与产线自动化实践 最近在搞STM32H5的安全产线方案调试口保护这块绕不开DA证书链。最开始我图省事直接在STM32TrustedPackageCreator里点鼠标点完发现一个严重问题产线几十块板子每块板子的证书都不一样GUI点一次可以点几十次会点吐而且没法保证每次参数一致。后来翻出LAT1605这个应用笔记换成用命令行生成DA证书链情况马上不一样了。这篇笔记我会把整个思路、工具参数、可复用脚本和踩过的坑都摊开讲给你一套能直接搬走的方案。1. 先从“为什么”说起DA证书链和命令行到底解决什么问题1.1 DA调试认证给调试口加一道“门禁”STM32H5默认带TrustZone和安全启动芯片里可以同时放普通代码、安全代码、密钥和证书。这时候最关键的一个问题就来了调试口怎么办如果调试口不设防攻击者拿个ST-Link就能把Flash内容完整读出来前面做的安全设计全部白搭。DADebug Authentication调试认证解决的就是这个调试者必须出示由OEM私钥签发的证书并完成挑战-响应式认证才有权限打开调试口。用一句话概括它把你的调试口从“一把钥匙”改成了“一张门禁卡”。为什么是证书链而不是单张证书因为根证书是OEM自己保管的“最高权限”平台证书和设备证书是逐级下发的“通行证”。哪怕某张设备证书泄露了攻击者也只能调试那一台设备没办法伪造其他设备根私钥始终在你自己手里。这个层级关系是证书链的核心价值。在STM32H5的应用笔记里DA证书链通常包含Root、OBE、OBR、RMA等分类对应不同调试权限和产品阶段实际烧录时要根据当前是开发、量产还是返修来选择对应证书。我一开始也想不通为什么不能直接拿根私钥给每台设备签证书非要分两层甚至三层。后来在项目里想明白了如果每台设备都直接用根私钥签名那把根私钥拿出来做签名的次数会非常多暴露风险大幅增加。中间加一层平台证书设备证书由平台私钥签发根私钥只用来签少数平台证书这样安全性高很多也方便做权限回收。这就是工程上常见的“最小授权”思路证书链的优势不是增加复杂度而是把风险收敛到可控范围。1.2 为什么我最终选了命令行而不是GUISTM32TrustedPackageCreator的图形界面做得确实不错第一次用的时候照着界面点完证书就出来了感觉挺简单。但实际用下来发现几个问题第一每次点选都依赖人工参数很难保证完全一致第二批量场景下效率低得吓人第三也是最致命的没法进自动化产线。现代产线基本都有审计和可复现性要求GUI点出来的东西没有脚本记录出了问题很难追溯。命令行就不一样把命令写成脚本所有参数明明白白摆在那里每次执行结果都一样CI/CD流程可以直接调用。尤其当你维护的板卡型号多、证书策略不同的时候命令行几乎是唯一靠谱的选项。我后来把所有命令都收进Git仓库每次变更都有记录排查问题的时候可以直接看历史这一点在过认证或对客户交代时非常有用。2. 动手之前环境准备与工具参数梳理2.1 你需要准备哪些东西在开始敲命令之前先把材料备齐否则过程中很容易卡壳。我实际用的环境是Windows 10做开发机Linux服务器做批量签名两边都跑通过下面列的是通用清单一块STM32H5目标板以及对应的ST-Link调试器用于后续烧录验证。STM32TrustedPackageCreator本文后面简称TPC确认安装时把CLI组件一起装上有些精简安装不会带命令行入口。OpenSSL用来生成根密钥和最终验证证书链免费的Windows下建议装一个顺手版本。安全材料根密钥、根证书密码、平台密钥这些要提前规划好特别是密码策略。产品唯一ID清单批量签发设备证书时用可以从板子上读出来整理成CSV或文本文件。这里有个容易忽略的点密钥和证书是两种东西。密钥是保密的证书是公开的。别把私钥和证书放在同一个公开目录里哪怕在开发阶段也应该从一开始就养成分类存放的习惯。我自己一开始图方便把所有文件扔一个文件夹后来整理的时候头大干脆全部重新生成了一轮。2.2 CLI入口和基本调用姿势TPC安装完成后命令行入口通常会在安装目录下具体名字以你自己安装的版本为准。建议做两件事第一把这个目录加到系统PATH里省得每次敲全路径第二第一次运行时直接不带参数执行让它输出帮助信息确认当前版本支持哪些DA子命令。CLI的调用逻辑并不复杂核心是传一个类似-DA的动作标识然后带上生成证书所需的参数。我给一个简化模板实际参数名以工具自带的帮助输出为准不同小版本可能存在差异CLI可执行文件名 -DA \ -action generate \ -certType 证书类型 \ -keyType RSA|ECC \ -keySize 位长 \ -rootKey 根私钥路径 \ -password 根私钥密码 \ -output 输出文件路径第一次跑的时候建议先用-help或者直接不带参数跑一遍把输出保存成文本后面写脚本时对着这个文本一点点填参数能少走很多弯路。我见过有人直接复制网上的命令结果版本对不上报错半天才开始查帮助反而更浪费时间。还有几个实操细节值得注意路径里不要有中文和空格命令行工具有时候会因为解析问题报一些莫名其妙的错误密码别直接写在脚本历史里优先用环境变量传递输出目录要提前创建好很多CLI工具不会自动建目录目录不存在会直接报错退出。3. 一步步生成你的证书链3.1 第一步生成根证书根证书是整个证书链的源头最稳妥的做法是先生成根私钥再基于它生成自签名根证书。我推荐用ECC-384而不是RSA-2048原因有三个STM32H5内置了ECC硬件加速签名验证更快ECC证书体积更小对MCU存储开销友好安全性在当前应用场景下完全足够。如果你愿意这一步可以用OpenSSL来做生成根材料更灵活也方便后续在其他流程里复用。我的做法是这样的openssl ecparam -name prime256v1 -genkey -noout -out root_key.pem openssl req -new -x509 -key root_key.pem -out root_cert.pem -days 3650 -subj /CNMyProduct Root CA第一行生成ECC私钥文件第二行基于这个私钥生成自签名根证书有效期10年。注意上面命令生成的私钥没有加密实际使用必须加密码保护。OpenSSL生成带密码的私钥可以按提示操作生成加密私钥或者在生成后单独用工具加密存储结合你本地的密码管理习惯来定。根证书的有效期不要设太长10年已经不少了。这个时间要和产品生命周期对齐宁可到期前提前安排迁移也不要设一个99年让人彻底忘掉后面芯片里的信任根想再更新会更麻烦。根私钥一定要设密码而且密码要单独保存在密码管理器或离线环境里可以说这是整个安全体系里最重要的一份秘密。3.2 第二步签发平台证书与设备证书证书树建议分成两级平台证书和设备证书。平台证书由根私钥签发之后批量给设备签证书时只用平台私钥设备证书由平台私钥签发每台设备一份里面可以包含设备唯一ID、授权调试范围、有效期等信息。用TPC的CLI生成平台证书命令大概是这个风格CLI -DA -action generate \ -certType Platform \ -keyType ECC -keySize 384 \ -rootKey root_key.pem -password $ROOT_PASS \ -output platform_cert.der生成设备证书开发阶段时把根密钥换成平台密钥同时加上设备UIDCLI -DA -action generate \ -certType Device \ -keyType ECC -keySize 384 \ -platformKey platform_key.pem -password $PLATFORM_PASS \ -deviceUid 0xXXXXXXXX \ -output device_cert.der关于证书类型的叫法ST生态里DA界面常见有OBE、OBR、RMA等分类实际对应的是不同使用阶段比如开发调试、量产锁定后的返修、退换货分析。这里我用Platform/Device粗粒度来讲具体到自己项目按照工具界面上的名称选即可。重点是把“谁签谁”的关系理清楚别把设备证书拿去当平台证书用也别把平台证书直接烧到设备上不然权限范围就乱了。我自己的经验是在批量生成时把每块板子的芯片唯一ID写进设备证书。STM32H5每颗芯片的UID是唯一的这样证书和设备就绑定了。调试口打开时校验的不只是“证书有效”还包括“这颗芯片就是证书上写的这颗”。如果没有这一步证书被复制到别的板子上也能用那就等于安全设计白做了。这个绑定关系在批量产线里尤其重要相当于给每台设备发了一张只能自己用的门禁卡。3.3 第三步输出文件整理与验证生成之后你会得到一堆.pem和.der文件。建议按目录分好不要图省事全部放一个目录certs/ root/ # 根私钥和根证书私钥离线保存 platform/ # 平台私钥和平台证书 devices/ # 每台设备的证书按UID命名子目录最关键的一步是验证证书链别生成完就以为完事。用OpenSSL验证是最直观的方式openssl verify -CAfile root_cert.pem -untrusted platform_cert.pem device_cert.pem结果会输出OK或者报错。如果验证通过再执行下一步把根公钥哈希写入H5的OTP区域。这一步起到“锚点”作用芯片只会信任这个根下面的证书链。写OTP是单向操作一旦写入就不能更改所以做之前务必确认密钥和证书已经备份好不要等烧完才发现私钥密码忘了。TPC的CLI可能也自带校验子命令但OpenSSL验证更直观而且不依赖特定软件项目交付时还能把验证命令写进文档里给客户复现。我每次发版前都会跑一遍这个验证命令并把它输出到构建日志里作为质量记录存档。4. 把证书链生成放进自动化流程4.1 批量生成多设备证书的脚本模板单张证书手动敲命令还行一旦设备数量上来就必须写脚本。我实际用得比较多的是一个批量脚本逻辑很简单读取一个包含设备UID的CSV文件循环调用CLI生成证书每份证书输出到以UID命名的文件夹同时生成一份日志方便排查哪些设备失败了。下面是一个Shell脚本示例Linux和Windows的WSL环境都能跑#!/bin/bash # batch_gen_certs.sh CSV_FILEdevices.csv while IFS, read -r uid product_type; do echo generating cert for $uid CLI -DA -action generate \ -certType Device \ -keyType ECC -keySize 384 \ -platformKey platform_key.pem \ -password $PLATFORM_PASS \ -deviceUid $uid \ -output devices/$uid/${uid}_cert.der logs/gen_${uid}.log 21 if [ $? -ne 0 ]; then echo ERROR: $uid failed, see logs/gen_${uid}.log fi done $CSV_FILE这个脚本最简单的形态但有几个关键点值得注意每个证书单独生成日志出问题能直接定位是哪台设备失败不用在一大堆输出里翻找。平台私钥密码通过环境变量$PLATFORM_PASS传入不要写死在脚本里否则一旦脚本泄露全部证书都等于没加保护。每台设备证书输出到以设备UID命名的目录和后续烧录/产测程序对应起来生产管理会很清晰。Windows产线环境通常用PowerShell思路完全一样无非是把循环语法换成foreach环境变量换成$env:PLATFORM_PASS。换汤不换药核心是日志、隔离、权限这三个点。4.2 密钥、密码与权限保护这部分我吃了不少亏专门拿出来说。根密钥和平台密钥必须分开存放根密钥最好离线保存甚至放到不联网的机器上。如果CI服务器要执行签名命令把密码存到CI平台的secret管理里不要放到配置文件或环境变量文件中直接提交到仓库。每次生成设备证书建议限定有效期不是越长越好。开发阶段设置365天左右足够防止“万能调试证书”长期有效。万一某台开发机的私钥泄露了至少一年后证书自动过期影响面可控。临时文件处理也是一个容易被忽略的点。TPC在生成过程中可能会产生临时文件脚本结束前记得清理。有次我在共享服务器上生成证书忘了清临时目录结果其他同事在公共目录里看到了私钥文件吓得我赶紧统一作废重签。这种问题不会频繁发生但一次就够让人长记性。5. 常见问题与排查速查表5.1 生成报错、退出码非0的常见坑命令行工具报错有时候很笼统我把实际遇到的典型问题整理成了表格方便按图索骥现象可能原因解决办法提示找不到根密钥或密码错误路径不对或密码变量没传进去使用绝对路径用echo检查变量是否为空输出目录不存在报错CLI不会自动创建目录脚本里先执行mkdir -p证书类型参数不识别当前CLI版本和文档版本不一致先运行-help查看当前支持参数生成成功后openssl verify失败证书链顺序或中间证书缺失按root-platform-device顺序用-untrusted拼接提示key size不支持选择了工具不支持的算法位长改用ECC-384或RSA-2048以工具提示为准如果一条命令反复报错优先检查“环境变量是不是没生效”和“路径里是不是有空格或中文”。命令行工具有时候两种错误会返回同一个通用错误码这时候别死磕报错码把命令一行行拆开分别用绝对路径执行通常能快速定位。5.2 证书生成成功但上板验证失败的排查路径证书生成成功不代表烧录后能通过我遇到过好几种情况。最常见的几个信任根不匹配芯片OTP里烧的根公钥哈希和你生成证书用的根证书不是同一把。这种问题最隐蔽两边单独看都不报错一对接才发现对不上。证书类型用错把开发证书当RMA证书用权限范围不对DA认证时直接被拒。时间或有效期问题设备证书过期或者板子内部RTC没有初始化导致认证时认为证书不在有效期内。调试口状态问题芯片已经进入最高锁定状态但你没提供对应RMA证书。排查路径我建议按顺序来先用openssl verify本地验证证书链是否完好再用ST的工具读一次芯片OTP里的根公钥哈希和手上的根证书比对然后把所有证书的有效期打印出来确认当前时间在有效范围内。按这个顺序走绝大多数问题都能定位。我自己之前就犯过把测试板OTP烧成了另一台机器的根哈希结果换了一批板子后证书全不认排查了很久才发现是OTP烧错。后来我把OTP写入流程也脚本化每次烧录前先做哈希比对这个问题再没出现过。最后再分享一点体会在证书链这个环节最费时间的往往不是命令本身而是先想清楚“你要保护什么、谁有权限、证书有效期怎么定、密钥怎么存”。我一开始就是因为没想清楚直接拿GUI点了几张证书出来结果到了产线阶段又要推倒重来。如果你正在做STM32H5的安全方案我建议先画一个简单的权限矩阵再把LAT1605里的命令行流程完整跑一遍把这个流程固化到脚本和文档里。这套东西一旦跑通后面无论是几十块开发板还是上千块的量产板都能轻松应对。
返回列表