我的 (r,s) 格式如下:["r","442ca7cb054a9862ed93848cc13e0134968eba79db89e0e6f9ded510149aacd1","s","5494856cc4e6ea054480605bcdf9a643f7efe0020e369fa01e5bab5d108bdbd7"]
如何将签名转换为 openssl 可以处理的格式 (DER、ASN.1) 并能够验证它?
我试图运行openssl dgst -sha1 -verify publKey.pem -signature signature SamplePDF.pdf
,签名是一个包含前面提到的文本的 .file 文件。
另外值得一提的是,我正在使用 ECDSA 和 secp256k1 曲线。
答案1
由于您的 r 和 s 值都是“低半”,即它们的第一个字节(十六进制 44 或 54)小于十六进制 80,如果您有(或得到)xxd
:
echo 30440220{rval_in_hex}0220{sval_in_hex} | xxd -p -r >sigfile
或者如果你有 bash 或 GNU 或其他 printf(更正:POSIX 不够用):
printf "$( echo ...asabove... | sed 's/../\\x&/g' )" >sigfile
或者更复杂,但也适用于“高半”值,创建一个包含
asn1=SEQUENCE:seq
[seq]
r=INTEGER:0x{rvalue_in_hex}
s=INTEGER:0x{svalue_in_hex}
然后运行openssl asn1parse -genconf thatfile -out sigfile
。在某些 shell 上,你可以创建一个临时文件来代替永久文件,如下所示:
openssl asn1parse -genconf <( printf "%s\n" "asn1=SEQUENCE:seq" "[seq]" ... ) -out sigfile
请注意,最佳做法是将哈希的强度与 PKC 相匹配,因此对于 secp256k1,您应该使用 SHA256(或 SHA3-256(如果可用)例如 OpenSSL 1.1.1 并且您喜欢),否则您基本上会浪费一些您花费资源的安全性。特别是因为 SHA1 已被破解为碰撞;请参阅https://shattered.io以及有关 crypto.SX 和 security.SX 的众多相关问题。