【问题标题】:OpenSSL : Encrypt with private key and decrypt with public key in RSAOpenSSL:在 RSA 中使用私钥加密并使用公钥解密
【发布时间】:2020-02-28 00:30:59
【问题描述】:

我想使用带有 RSA 算法的 OpenSSL 使用私钥加密文件:

openssl rsautl -in txt.txt -out txt2.txt -inkey private.pem -encrypt

现在如果我进行解密操作:

openssl rsautl -in txt2.txt -pubin -inkey public.pem -decrypt

此操作需要私钥

我知道我应该使用公钥来加密,如果我使用私钥,我会得到一个签名。

但是,我想这样做是为了学习。

【问题讨论】:

  • 我的猜测是,在第一个命令中,即使您传递了一个私钥,它也只是将文件的前两个组件作为公钥读取,并且正在执行公钥操作。您必须使用 sign 和 verify 子命令来执行您想要执行的操作。

标签: encryption rsa digital-signature signature


【解决方案1】:

您错误地使用了密钥。在公钥加密中,加密使用公钥:

openssl rsautl -in txt.txt -out txt2.txt -inkey public.pem -pubin -encrypt

而对于解密,使用与公钥相关的私钥:

openssl rsautl -in txt2.txt -inkey private.pem -decrypt

私钥(没有 -pubin)可用于加密,因为它实际上包含公共指数。请注意,RSA 通常不应用于直接加密数据,而只能用于“封装”(RSA-KEM)或“包装”用于对称加密的密钥。

但你提到你实际上想研究签名。尽管历史上 RSA 签名有时被描述为“使用私钥加密”,但这种描述具有误导性,并且实际实施被发现是不安全的。签名和验证实际上是与加密和解密分开的不同操作,rsautl 只执行其中的部分。例如,您可以这样做:

# hash the data and encode the result in ASN.1 
openssl rsautl -sign -in hashenc.dat -out sig.dat -inkey private.pem
...
# on the recipient (with signature and purportedly correct data)
openssl rsautl -verify -in sig.dat -out hashenc.dat -inkey public.pem -pubin 
# or often more appropriate use a certificate for the public key
openssl rsautl -verify -in sig.dat -out hashenc.dat -inkey cert.pem -certin
# now either decode hashenc.dat and compare the hash
# to a new hash of the data (which should be the same)
# or compare all of hashenc.dat to an encoding of a new hash

最好使用openssl dgst 来执行PKCS1 e.g. rfc8017 指定的整个签名和验证序列。例如,对于 RSASSA-PKCS1v1_5 签名使用 SHA256

openssl dgst -sha256 -sign private.pem -in data.txt -out sig.dat
# or can be abbreviated
openssl sha256 -sign private.pem -in data.txt -out sig.dat
# hashes the data, encodes the hash, does type 1 padding and modexp d
...
openssl dgst -sha256 -verify public.pem -in data.txt -signature     sig.dat
# or abbreviated 
openssl sha256 -verify public.pem -in data.txt -signature sig.dat 
# does modexp e and type 1 unpadding, and compares the result to a hash of the data

# notice you don't specify which key is public or private
# because this command knows what to expect

# however it does not accept the public key from a certificate, 
# you must extract the public key from the cert first

这种形式(但不是rsautl)还支持更新的、技术上更好的、但没有广泛使用的PSS填充。这仅在 dgst 手册页中引用,并且大部分记录在 pkeyutl 手册页中,这并不完全明显。

在其他更符合主题的堆栈上,请参阅例如: https://security.stackexchange.com/questions/93603/understanding-digitial-certifications
https://security.stackexchange.com/questions/87325/if-the-public-key-cant-be-used-for-decrypting
https://security.stackexchange.com/questions/11879/is-encrypting-data-with-a-private-key-dangerous
https://security.stackexchange.com/questions/68822/trying-to-understand-rsa-and-its-terminology
https://crypto.stackexchange.com/questions/2123/rsa-encryption-with-private-key-and-decryption-with-a-public-key
https://crypto.stackexchange.com/questions/15997/is-rsa-encryption-the-same-as-signature-generation
https://crypto.stackexchange.com/questions/15295/why-the-need-to-hash-before-signing-small-data

【讨论】:

  • @dave_thompson_085 感谢您的编辑。你想以社区的形式给出这个答案吗?
  • 我看不出有任何理由;在我看来,它现在既完整又正确,没有必要鼓励进一步的改变。当然,与 Stack 一样,任何想要进一步更改的人(其他)都可以提出或提出要求。