openSSL rsautl和dgst之间的区别

27
以下命令为输入文件生成签名:
openssl dgst -sha1 -sign privateKey.pem -out signature1 someInputFile
以下命令也可为输入文件生成签名:
openssl dgst -binary -sha1 someInputFile > digest
openssl rsautl -sign -in digest -inkey privateKey.pem -out signature2
据我所知,它们都应该创建SHA1摘要的RSA签名。但是它们生成的签名不同。
因此,使用方法2生成的签名也无法通过"openssl dgst -verify"调用进行验证。
有人知道它们之间的区别是什么,以及如何解决吗?

2
正确答案在 https://dev59.com/rG435IYBdhLWcg3w6EmF 中提供。M'vy 表明,“rsautl -sign” 在输出签名文件中包含输入文件的加密内容(或您的情况下的摘要)。要仅进行原始 RSA 签名,请使用“openssl pkeyutl”,如 https://dev59.com/TWDVa4cB1Zd3GeqPfrCg#10443732 所述。 - Jonathan Ben-Avraham
@JonathanBen-Avraham 很好,Jonathan。你能把它作为答案提供吗?那我就可以接受它了。 - fishinear
2个回答

27

简单地说,dgst -sign 会创建一个哈希值,将其 ASN1 编码,然后签署这个 ASN1 编码的哈希,而 rsautl -sign 则直接对输入进行签署,无需进行哈希或 ASN1 编码。两种方法都会将输入数据与签名一起包含在输出中,而不仅仅是输出签名。以下是一个 Bash 脚本,展示了 openssl dgst -signopenssl rsautl -sign 之间的差异。

#!/bin/bash
# @(#) Bash script demos difference between openssl rsautl and dgst signing
# Usage: $0 <name of file to sign> <private key file, without passphrase>

# 1. Make an ASN1 config file

cat >asn1.conf <<EOF
asn1 = SEQUENCE:digest_info_and_digest

[digest_info_and_digest]
dinfo = SEQUENCE:digest_info
digest = FORMAT:HEX,OCT:`openssl dgst -sha256 $1 |cut -f 2 -d ' '`

[digest_info]
algid = OID:2.16.840.1.101.3.4.2.1
params = NULL

EOF

# If you are wondering what the "algid = OID:2.16.840.1.101.3.4.2.1" is, it's
# the SHA256 OID, see http://oid-info.com/get/2.16.840.1.101.3.4.2.1

# 2. Make a DER encoded ASN1 structure that contains the hash and
# the hash type
openssl asn1parse -i -genconf asn1.conf -out $1.dgst.asn1

# 3. Make a signature file that contains both the ASN1 structure and
# its signature
openssl rsautl -sign -in $1.dgst.asn1 -inkey $2 -out $1.sig.rsa

# 4. Verify the signature that we just made and ouput the ASN structure
openssl rsautl -verify -in $1.sig.rsa -inkey $2 -out $1.dgst.asn1_v

# 5. Verify that the output from the signature matches the original
# ASN1 structure
diff $1.dgst.asn1 $1.dgst.asn1_v

# 6. Do the equivalent of steps 1-5 above in one "dgst" command
openssl dgst -sha256 -sign $2 -out $1.sig.rsa_dgst $1

# 7. Verify that the signature file produced from the rsautl and the dgst
# are identical
diff $1.sig.rsa $1.sig.rsa_dgst

请查看我在评论中提供给原帖作者的致谢。


这很好!但是步骤2和3中创建的asn1文件包含文件($0)的sha256摘要,而不是完整的签名。 - user1511417
pkeyutl -sign -pkeyopt digest:$hash(自2010年1.0.0版本起可用)要简单得多。或者查看PKCS1=rfc2437/rfc3447/rfc8017中的前缀常量。 - dave_thompson_085

3

5
谢谢你的提问。根据我理解,创建数字签名就是使用私钥加密哈希值。在第一种方法中,我需要指定使用SHA1哈希算法并使用私钥对哈希值进行签名,这与第二种方法相同。你知道第一种方法与第二种方法有什么不同吗? - fishinear

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接