4. 使用RSA私钥对固件哈希签名

任务目标

使用RSA私钥对固件镜像的SHA-256哈希值进行数字签名,生成二进制签名文件,并验证签名长度符合RSA密钥模长(本例为2048位,签名长度应为256字节)。

环境与依赖

  • 操作系统:Linux/macOS/Windows(均适用)
  • 工具:OpenSSL命令行(版本1.1.1或以上)
  • 输入文件:firmware.bin(任意内容的固件镜像,本例使用随机数据生成)

实现步骤与代码

以下命令完成从密钥生成到签名验证的完整闭环。核心操作为:生成RSA私钥 → 计算固件SHA-256哈希 → 使用私钥对哈希签名 → 输出签名文件并检查长度。

#!/bin/bash
# 1. 生成测试用固件(模拟真实固件镜像)
dd if=/dev/urandom of=firmware.bin bs=1024 count=4 status=none

# 2. 生成RSA-2048私钥(PKCS#1格式)
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
    -out private_key.pem

# 3. 从私钥提取公钥(后续验证用)
openssl pkey -in private_key.pem -pubout -out public_key.pem

# 4. 计算固件SHA-256哈希
openssl dgst -sha256 -binary firmware.bin > firmware.sha256

# 5. 使用RSA私钥对哈希签名(输出二进制签名)
openssl pkeyutl -sign -inkey private_key.pem \
    -in firmware.sha256 -out firmware.sig

# 6. 验证签名长度(应为256字节 = 2048位/8)
SIG_SIZE=$(stat -c%s firmware.sig 2>/dev/null || stat -f%z firmware.sig)
echo "签名文件大小: ${SIG_SIZE} 字节"

# 7. 使用公钥验证签名(确认签名有效)
openssl pkeyutl -verify -pubin -inkey public_key.pem \
    -in firmware.sha256 -sigfile firmware.sig \
    && echo "签名验证通过"

运行方式

  1. 将上述脚本保存为 sign_firmware.sh;
  2. 赋予执行权限并运行:chmod +x sign_firmware.sh && ./sign_firmware.sh;
  3. Windows用户可在Git Bash或WSL中执行相同命令。

验证方法与判定标准

  • 签名长度验证:脚本输出“签名文件大小: 256 字节”即通过。RSA-2048签名长度恒等于模长(256字节),与固件内容无关。
  • 签名有效性验证:脚本输出“签名验证通过”即表示签名与固件哈希匹配。若验证失败,说明签名过程或密钥使用有误。
  • 完整性检查:可手动执行 xxd firmware.sig | head 查看签名文件为二进制非文本内容,且长度固定为256字节。

常见问题

  • 签名长度不是256字节:检查私钥是否为RSA-2048(openssl rsa -in private_key.pem -text -noout | head 可查看模长)。
  • 验证失败:确认签名时使用的哈希文件与验证时一致;若固件在签名后被修改,验证必然失败。
  • 跨平台兼容:stat命令在Linux/macOS参数不同,脚本已做兼容处理;若仍报错,可手动用 ls -l firmware.sig 查看大小。