为何source脚本时OpenSSL verify次次成功,直接执行却80%失败?
问题:脚本直接执行验证签名大概率失败,source执行则正常
问题详情
执行source ./script.sh时脚本每次都能返回Verified OK,但直接运行./script.sh时约80%概率返回Error verifying data,仅少数情况成功。即使将签名保存到文件中,问题依然存在。
脚本内容
#!/bin/bash signing_input="Hi." signature=$(echo -n "$signing_input" | openssl dgst -sha256 -sign private.pem) echo -n "$signature" | openssl dgst -sha256 -verify public.pem -signature <(echo -n "$signature")
密钥生成命令
openssl ecparam -name secp256k1 -genkey -noout -out private.pem openssl ec -in private.pem -pubout -out public.pem
环境:Mac M1,iTerm2,zsh
原因分析
问题核心是echo命令处理二进制签名数据的行为差异:
- OpenSSL生成的ECDSA签名是二进制数据,包含大量非打印/特殊控制字符。
- 直接执行脚本时,用的是bash的
echo,它默认会解析转义字符,导致二进制签名数据被篡改或截断。 source执行时,脚本在zsh环境下运行,zsh的echo默认不解析转义字符,能完整保留二进制数据,因此验证成功。
解决方案
将脚本中所有echo -n替换为printf "%s",printf不会解析转义字符,能准确输出二进制数据。修改后的脚本如下:
#!/bin/bash signing_input="Hi." signature=$(printf "%s" "$signing_input" | openssl dgst -sha256 -sign private.pem) printf "%s" "$signing_input" | openssl dgst -sha256 -verify public.pem -signature <(printf "%s" "$signature")
也可以通过临时文件传递签名,避免变量处理的问题:
#!/bin/bash signing_input="Hi." printf "%s" "$signing_input" | openssl dgst -sha256 -sign private.pem > signature.bin printf "%s" "$signing_input" | openssl dgst -sha256 -verify public.pem -signature signature.bin rm signature.bin
内容的提问来源于stack exchange,提问作者Trent
相关产品推荐
相关产品推荐

