Encryption OpenSSL-正确的RSA签名生成和验证

Encryption OpenSSL-正确的RSA签名生成和验证,encryption,openssl,rsa,digital-signature,Encryption,Openssl,Rsa,Digital Signature,我正在学习一些OpenSSL RSA的用法。我注意到有两种不同的方法来生成和验证文件签名。一个使用openssl-dgst1,另一个使用openssl-pkeyutl1,它们似乎都可以验证、接受私有和公共证书、输出签名文件、接受算法,但它们不能互换。openssl pkeyutl生成的签名在验证中不能作为openssl dgst的签名使用,反之亦然。即使两个签名文件具有相似的数据结构格式 注意:这是专门针对RSA证书的。我不完全确定X.509证书是否存在同样的可能性 问题:哪种用法更合适?ope

我正在学习一些OpenSSL RSA的用法。我注意到有两种不同的方法来生成和验证文件签名。一个使用openssl-dgst1,另一个使用openssl-pkeyutl1,它们似乎都可以验证、接受私有和公共证书、输出签名文件、接受算法,但它们不能互换。openssl pkeyutl生成的签名在验证中不能作为openssl dgst的签名使用,反之亦然。即使两个签名文件具有相似的数据结构格式

注意:这是专门针对RSA证书的。我不完全确定X.509证书是否存在同样的可能性

问题:哪种用法更合适?openssl pkeyutl还是openssl dgst

方法1:openssl dgst

目录/ test.txt-用于创建签名的文件 cert.pem-私有/公共RSA密钥,通过PKCS8使用hmacWithSHA256加密 cert.pub.pem-使用` openssl rsa-pubout'提取cert.pem的公钥` test.sig—由OpenSSL创建的文件签名 创建test.sig $openssl dgst-sha256-sign cert.pem-out test.sig test.txt 为cert.pem:test输入通行短语 使用私钥进行验证 $openssl dgst-sha256-验证cert.pub.pem-签名测试.sig测试.txt 确认正常 使用公钥进行验证 $openssl dgst-sha256-prverify cert.pem-signature test.sig test.txt 为cert.pem:test输入通行短语 确认正常 方法2:openssl pkeyutl

目录/ test.txt-用于创建签名的文件 cert.pem-私有/公共RSA密钥,通过PKCS8使用hmacWithSHA256加密 cert.pub.pem-使用` openssl rsa-pubout'提取cert.pem的公钥` test.sig—由OpenSSL创建的文件签名 创建test.sig $openssl pkeyutl-sign-in test.txt-out test.sig-inkey cert.pem 为cert.pem:test输入通行短语 使用私钥进行验证 $openssl pkeyutl-verify-sigfile test.sig-in test.txt-inkey cert.pub.pem-pubin 签名验证成功 使用公钥进行验证 $openssl pkeyutl-verify-sigfile test.sig-in test.txt-inkey cert.pem 为cert.pem:test输入通行短语 签名验证成功
好的,第一次我没注意到你在第二个方法中忽略了任何散列。大多数人无意中发现了正确的哈希和使用dgst-sign的签名与使用dgst和rsautl或pkeyutl的稍微不正确的哈希和签名之间的区别,而不仅仅是您所做的完全不正确的签名

所以答案是:只有pkeyutl是完全错误的。只有罗萨特尔一个人

RSA签名原语本身仅限于少量数据,主要取决于密钥大小,目前约为240字节。大多数应用程序,如文档、电子邮件、代码和通信SSH、SSL/TLS,都需要处理更多的数据,因此我们总是先对数据进行散列,然后RSA对散列加填充进行签名,这通常就是问题所在,请参见下文。DSA和ECDSA以及EdDSA的一种变体也是如此,尽管首选的EdDSA变体使用不同的解决方案

参见或其任何前身,注释8.2.1结合9.2给出了一个四步过程:散列数据,“编码”ASN.1中的散列,它有效地添加了前缀填充,如“注释”所示,用另一个填充块类型1显式填充编码的散列,最后计算RSA原语rd mod n。8.2.2中的验证也会执行相同的操作,但会反转RSA原语

openssl dgst-$hash-sign pubkey正确执行组合过程

openssl dgst-$hash-binary | openssl pkeyutl-sign-pkeyopt digest:$hash虽然更复杂,但也是正确的

openssl dgst-$hash-binary | openssl pkeyutl-无符号-pkeyopt或 openssl dgst-$hash-binary | openssl rsautl-sign是错误的,但微妙地是错误的;他们使用哈希填充符号,这似乎是正确的,但他们不使用ASN.1填充部分。 这就是我之前认为是重复的许多Qs中解释的差异

使用临时文件或其他介质代替管道有效完成相同工作的变化同样正确或不正确;这允许将操作的散列部分与其他部分分离,如果数据位于与密钥不同的系统或设备上,或者反之亦然,这将非常有用

没有前面散列步骤的openssl pkeyutl-sign显然是错误的

我不太清楚您对“RSA证书”和“X.509证书”的要求。您使用的两种文件格式—PKCS8表示privatekey,OpenSSL称PUBKEY为PUBKEY表示PUBKEY—都是密钥,而不是任何类型的证书,即使您错误地将它们的名称以cert开头。这两种文件格式都是“通用”的—它们支持多种算法,包括RSA和许多其他算法。X.509证书包含公钥和许多其他数据,以及 是一种不同的通用格式,支持RSA和许多其他算法。因此,您可以拥有一个privatekey PKCS8文件,其中包含一个RSA privatekey,通常简称为RSA privatekey文件;一个publickey文件,其中包含一个RSA publickey,通常简称为RSA publickey文件;和/或一个X.509证书文件,其中包含一个RSA publickey,通常简称为RSA证书

dgst-签名/验证仅分别使用私钥或公钥文件,而不使用证书。它不仅支持RSA,还支持多种算法


pkeyutl-sign只使用privatekey文件,但是-verify可以使用privatekey文件、公钥文件或证书文件,后面两个文件可以使用-pubin或-certin。它支持多种算法。rsautl接受相同的文件格式,但仅支持RSA

Dupe还交叉和@dave_thompson_085-首先,我知道这两个工具生成不同的数据。第二,您的第一个重复是比较rsautl和dgst,而不是dgst和pkeyutl。第三个问题由pkeyutl解决。3、4、5 dgst和rsautl。6,7,又是404,8。我知道他们的散列方式不同。哪一个是合适的?这就是问题所在。@dave_thompson_085是的,我知道openssl dgst-sha256和openssl pkeyutl-pkeyopt摘要之间有区别:sha256,它们不一样。非常感谢您的详细解释。特别是关于PKCS8私钥、RSA公钥和X.509证书的应用。以及有关填充用法的说明。对于不正确的术语和引用,我深表歉意。