You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移植Xilinx U-Boot RSA验签代码后验证失败,求排查修正

问题分析与修正方案

我来帮你梳理下可能导致RSA验签结果异常的几个关键问题,以及对应的修正步骤:

1. 签名的端序格式不匹配

OpenSSL生成的十六进制签名是大端序的字节流,但U-Boot的rsa_mod_exp_sw函数要求输入的签名是小端序的uint32数组(和公钥的modulus/rr格式完全一致)。你直接将签名作为uint8数组传入,必然会导致模幂运算结果错误。

修正方法:

把OpenSSL输出的十六进制签名转换成符合要求的uint32数组:

  1. 将十六进制签名字符串转为大端字节数组(比如157eb60ad0c77427...转成0x15, 0x7e, 0xb6, 0x0a, 0xd0, 0xc7, 0x74, 0x27...)
  2. 按4字节为一组,反转每组内的字节顺序,得到小端uint32元素。例如第一组0x15,0x7e,0xb6,0x0a要转为0x0ab67e15,作为uint32数组的第一个元素
  3. 2048位签名对应64个uint32元素,确保转换后的数组长度和公钥的len字段(64)完全一致

2. 签名包含ASN.1哈希前缀

OpenSSL的openssl dgst -sign命令生成的签名,并不是直接对SHA256哈希值进行RSA签名,而是对带ASN.1编码前缀的哈希值签名。而U-Boot的rsa_mod_exp_sw只是执行原始的RSA模幂运算,输出的结果是带ASN.1前缀的完整数据,不是纯SHA256哈希值。

验证与修正:

  • 先验证签名的ASN.1结构:
    # 将十六进制签名转为DER格式文件,再解析ASN.1
    echo "你的十六进制签名字符串" | xxd -r -p > sig.der
    openssl asn1parse -inform DER -in sig.der
    
    你会看到类似输出,其中OCTET STRING部分就是你要的纯SHA256哈希:
    0:d=0  hl=4 l= 257 cons: SEQUENCE          
    4:d=1  hl=2 l=  13 cons: SEQUENCE          
    6:d=2  hl=2 l=   9 prim: OBJECT            :sha256
    17:d=2  hl=2 l=   0 prim: NULL              
    19:d=1  hl=4 l= 239 prim: OCTET STRING      [HEX DUMP]:你的SHA256哈希值
    
  • 两种修正路径:
    1. 解析输出结果:调用rsa_mod_exp_sw得到小端uint32数组后,先转成大端字节流,再解析ASN.1结构提取OCTET STRING部分,和openssl dgst -sha256 a.txt的结果对比
    2. 生成纯哈希签名:如果想直接得到纯哈希结果,改用以下命令生成签名(跳过ASN.1前缀):
      # 先生成a.txt的SHA256哈希,再对纯哈希做RSA签名
      openssl dgst -sha256 a.txt | cut -d' ' -f2 | xxd -r -p > hash.bin
      openssl rsautl -sign -inkey key.pem -raw -in hash.bin -out sig.raw
      # 转成十六进制查看
      xxd -p sig.raw
      
      用这个签名转换为小端uint32数组后,调用rsa_mod_exp_sw得到的结果就是纯SHA256哈希的小端uint32数组,转成大端字节流后和原哈希一致。

3. 公钥与签名的配对验证

确保你用dumppublickey生成的U-Boot格式公钥,和用来签名的私钥是配对的:

# 从私钥导出OpenSSL格式公钥
openssl rsa -in key.pem -pubout -out pub.pem
# 用dumppublickey重新处理这个公钥,对比生成的modulus、n0inv等字段和你当前使用的是否一致
dumppublickey pub.pem

如果字段不一致,说明公钥生成过程有误,会直接导致验签失败。

4. 输出结果的格式转换

rsa_mod_exp_sw的输出是小端序的uint32数组,你需要将其转换为大端字节流后再进行对比:

  • 遍历输出的uint32数组,每个元素按大端字节序拆分(比如0x0ab67e15拆成0x0a, 0xb6, 0x7e, 0x15)
  • 拼接所有字节得到完整的大端字节流,再和目标哈希(或ASN.1结构)对比

内容的提问来源于stack exchange,提问作者xutao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:09:12