openssl rsautl -in txt.txt -out txt2.txt -inkey private.pem -encrypt
现在,如果我执行解密操作:
openssl rsautl -in txt2.txt -pubin -inkey public.pem -decrypt
这个操作需要私钥
我知道在加密时应该使用公钥,而如果我使用私钥,则会得到一个签名。
但是,出于学习目的,我想这样做。
openssl rsautl -in txt.txt -out txt2.txt -inkey private.pem -encrypt
openssl rsautl -in txt2.txt -pubin -inkey public.pem -decrypt
这个操作需要私钥
我知道在加密时应该使用公钥,而如果我使用私钥,则会得到一个签名。
但是,出于学习目的,我想这样做。
您正在错误使用密钥。在公钥加密中,加密使用公钥:
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)或“包装”用于对称加密的密钥。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 例如rfc8017规定的整个签名和验证序列执行。例如,对于使用SHA256的RSASSA-PKCS1v1_5签名:
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
我看到你说“想为了学习目的而这样做”。那么,对于其他人来说,这也应该只用于“学习目的”,而不是任何生产或声称安全的系统。
正如@kelalaka所指出的,在公钥密码学中,公钥用于加密,私钥用于解密。然而,如果你正在学习RSA,你也知道“加密/解密”和“签名/验证”使用相同的基本数学公式:
m
提高到e
的幂次方,mod(n
),而解密将c
提高到d
的幂次方,mod(n
),其中(e, n)
是公钥,(d, n)
是私钥。鉴于这个数学基础,我认为一个自然的问题是,我们如何将m
提高到d
的幂次方,反之亦然?hash(m)
提高到d
的幂,mod(n
),而消息验证将tag
提高到e
的幂,mod(n
)。如果您宽松地定义“加密”为“将m
提高到一个数字的幂,mod (n
)”,那么Openssl CLI可以使用私钥“加密文件”(实际上是签名以创建tag
)。rsautl子命令可以这样使用(请注意,输入数据必须与用于加密/签名的密钥具有相同的位长度,因此需要501字节的“A”填充):
# Create the file to have a `tag` created for:
python3 -c "print('Hello World'+501*'A', end='')" > txt.txt
# Create a `tag` called `txt2.txt` for the `txt.txt` file:
openssl pkeyutl -sign -inkey private_key.pem -in tx.txt -out txt2.txt -pkeyopt rsa_padding_mode:none
现在,txt2.txt
包含将 txt.txt
提高到幂次方 d
,mod(n
) 的结果。
如果您宽泛地定义“解密”为“将 m
提高到一个数的幂次方,mod (n
)”,那么 Openssl CLI 可以“使用公钥解密文件”(实际上是验证,但可以查看中间步骤的原始结果)。可以像这样使用 rsautl
子命令:
openssl rsautl -verify -inkey public_key.pem -pubin -in txt2.txt -raw -hexdump
现在stdout
包含将txt2.txt
提高到e
次幂,模(n
)的结果。