如何修正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
已确认客户端与服务器使用的证书无误。
修正方案
验证失败的核心有两个问题:
- 填充方式未显式指定:OpenSSL默认的RSA验证填充逻辑和.NET的
RSASignaturePadding.Pkcs1不完全匹配,必须明确指定PKCS1填充模式。 - 哈希格式不匹配:服务器是对十六进制字符串解码后的原始哈希字节签名,而客户端生成的
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
相关产品推荐
相关产品推荐

