使用OpenSSL验证签名文档出现ECDSA_SIG ASN1编码错误如何解决
ECDSA签名验证失败(ASN.1解码错误)解决方案
错误原因
报错指向ECDSA_SIG结构的ASN.1解码失败,原因是OpenSSL的dgst命令默认期望签名文件为ASN.1/DER编码格式的ECDSA签名结构,你手头的sign.txt大概率属于以下两种不符合要求的情况:
- 签名是Raw格式:直接拼接了ECDSA签名的r、s两个大整数的二进制内容,没有ASN.1封装头
- 签名是Base64编码的文本格式,不是命令要求的二进制格式
解决步骤
步骤1:处理Base64编码的签名
如果打开sign.txt可见是由字母、数字、/、+、=组成的字符串,说明是Base64编码的签名,先转为二进制文件:
- Linux/macOS/Git Bash环境执行:
base64 -d sign.txt > sign.bin - Windows cmd环境执行:
certutil -decode sign.txt sign.bin
转换完成后先尝试用二进制签名验证:openssl dgst -sha256 -verify pub-key.txt -signature sign.bin msg.txt
如果仍报相同的ASN.1错误,说明签名是Raw格式,继续走下一步。
步骤2:Raw格式签名转ASN.1/DER格式
常用的secp256r1(prime256v1)、secp256k1曲线对应的Raw签名为64字节,前32字节为r值、后32字节为s值,执行以下命令将Raw签名封装为ASN.1格式:
openssl asn1parse -genconf <(printf "asn1=SEQUENCE:ecdsa_sig\n[ecdsa_sig]\nr=INTEGER:0x$(hexdump -v -e '/1 "%02x"' sign.bin | head -c 64)\ns=INTEGER:0x$(hexdump -v -e '/1 "%02x"' sign.bin | tail -c 64)") -out sign.der
无hexdump工具的Windows环境可先导出
sign.bin的十六进制内容,手动拆分前64个十六进制字符为r值、后64个为s值,替换上述命令中对应位置的十六进制值即可。
步骤3:正式验证签名
执行最终验证命令:
openssl dgst -sha256 -verify pub-key.txt -signature sign.der msg.txt
验证通过会输出Verified OK。
其他排查点
- 确认公钥格式正确:
pub-key.txt为标准PEM格式公钥,开头为-----BEGIN PUBLIC KEY-----,结尾为对应结束标识,无多余空行、特殊字符 - 确认哈希算法匹配:如果生成签名时使用的哈希算法不是SHA256,需将命令中的
-sha256替换为对应算法(如-sha512、-sm3等) - 确认原始消息未被篡改:
msg.txt的内容和签名时的原始内容完全一致,包括换行、空格等不可见字符
内容的提问来源于stack exchange,提问作者YASH TAILOR
相关产品推荐
相关产品推荐

