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

如何修正Shell脚本验证RSA PKCS1填充签名失败的问题?

问题描述

我们服务器团队用以下.NET代码为指定SHA256哈希生成签名:

Convert.ToBase64String(rsap.SignHash(SHA256.HashData(Convert.FromHexString(strHash)), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));

签名采用RSA PKCS1填充方式。客户端通过以下命令生成SHA256校验和:

sha256sum v.tgz | awk '{printf $1}' > chksum

我编写了Shell脚本验证服务器生成的签名,但执行时验证失败。怀疑是openssl dgst步骤未指定填充方式,请问该如何修正?

附客户端Shell脚本:

#!/bin/bash

file=$1
signature=$2
public_key=$3

if [[ $# -lt 3 ]] ; then
  echo "Usage: signature_verify <file> <signature> <public_key>"
  exit 1
fi

# Create checksum
sha256sum $file | awk '{printf $1}' > chksum

#decode the signature
cat $signature | openssl base64 -A -d > sign_dec

openssl dgst -sha256 -verify $public_key -signature sign_dec chksum

rm -rf chksum
rm -rf sign_dec

已确认客户端与服务器使用的证书无误。

修正方案

验证失败的核心有两个问题:

  1. 填充方式未显式指定:OpenSSL默认的RSA验证填充逻辑和.NET的RSASignaturePadding.Pkcs1不完全匹配,必须明确指定PKCS1填充模式。
  2. 哈希格式不匹配:服务器是对十六进制字符串解码后的原始哈希字节签名,而客户端生成的chksum是哈希的十六进制文本字符串,并非原始字节流,导致验证时哈希内容不一致。

修正后的脚本如下:

#!/bin/bash

file=$1
signature=$2
public_key=$3

if [[ $# -lt 3 ]] ; then
  echo "Usage: signature_verify <file> <signature> <public_key>"
  exit 1
fi

# 生成原始SHA256哈希字节流(而非十六进制文本)
sha256sum $file | awk '{printf $1}' | xxd -r -p > chksum_raw

# 解码签名
cat $signature | openssl base64 -A -d > sign_dec

# 显式指定PKCS1填充方式进行验证
openssl dgst -sha256 -sigopt rsa_padding_mode:pkcs1 -verify $public_key -signature sign_dec chksum_raw

# 清理临时文件
rm -rf chksum_raw sign_dec

关键修改说明

  • 新增xxd -r -p命令,将十六进制哈希文本转换为原始字节流,和服务器端Convert.FromHexString(strHash)处理后的哈希格式完全对齐。
  • 在openssl dgst命令中添加-sigopt rsa_padding_mode:pkcs1,明确指定PKCS1填充方式,匹配.NET的签名逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:26:05