如何使用公钥加密openssl中的大文件
Posted
技术标签:
【中文标题】如何使用公钥加密openssl中的大文件【英文标题】:How to encrypt a large file in openssl using public key 【发布时间】:2011-10-31 21:25:29 【问题描述】:我怎样才能用公钥加密一个大文件,这样除了拥有私钥的人之外,其他人都无法解密它?
我可以制作 RSA 公钥和私钥,但在使用此命令加密大文件时:
openssl rsautl -encrypt -pubin -inkey public.pem -in myLargeFile.xml -out myLargeFile_encrypted.xml
以及我如何也可以执行解密....
我通过以下命令创建我的私钥和公钥
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -outform PEM -pubout
我收到此错误:
RSA operation error
3020:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:.\crypto\rsa\rsa_pk1.c:151:
我尝试制作大小从 1024 到 1200 位的密钥,但没有运气,同样的错误
【问题讨论】:
【参考方案1】:公钥加密不适用于加密任意长的文件。一个使用对称密码(比如 AES)进行正常加密。每次生成、使用新的随机对称密钥,然后使用 RSA 密码(公钥)进行加密。密文与加密的对称密钥一起被传送给接收者。接收方使用自己的私钥解密对称密钥,然后使用对称密钥解密消息。
私钥永远不会共享,只有公钥用于加密随机对称密码。
【讨论】:
但是非对称加密的重点是防止共享私人秘密,这种方法会导致共享密钥,即使它是用非对称加密加密的。使用像 RSA 这样的非对称加密来加密有什么优势吗?共享密钥与对称算法 @techno:你没有分享任何秘密。您生成一次性随机密钥,使用它来加密单个消息,然后将其丢弃。您随消息发送的密钥仅对该消息有效。 是的,但是特定消息的一次性密钥是共享的,对吗?使用 RSA 等非对称加密技术来加密共享密钥与对称算法相比有什么优势 是的。您还共享消息本身。如果您害怕共享密钥,也不要共享消息。 @n.m. “公钥加密不用于加密任意长的文件。”,严格从性能的角度来看?使用 recipient(或应该读取文件的任何人)的公钥对整个文件进行 RSA 加密会带来其他缺点吗?【参考方案2】:在 OpenSSL 和命令行中安全和高度安全地编码任何文件的解决方案:
您应该准备好一些 X.509 证书来加密 PEM 格式的文件。
加密文件:
openssl smime -encrypt -binary -aes-256-cbc -in plainfile.zip -out encrypted.zip.enc -outform DER yourSslCertificate.pem
什么是什么:
smime - 用于 S/MIME 实用程序的 ssl 命令 (smime(1)) -encrypt - 选择的文件处理方法 -binary - 使用安全文件处理。通常,输入消息会按照 S/MIME 规范的要求转换为“规范”格式,此开关禁用它。所有二进制文件(如图像、声音、ZIP 档案)都需要它。 -aes-256-cbc - 选择 256 位密码 AES 进行加密(强)。如果未指定,则使用 40 位 RC2(非常弱)。 (Supported ciphers) -in plainfile.zip - 输入文件名 -out encrypted.zip.enc - 输出文件名 -outform DER - 将输出文件编码为二进制。如果不指定,文件采用base64编码,文件大小增加30%。 yourSslCertificate.pem - 证书的文件名。应该是 PEM 格式。该命令可以非常有效地对大文件进行强加密,无论其格式如何。已知问题: 当您尝试加密大文件 (>600MB) 时发生错误。没有错误抛出,但加密文件将被损坏。始终验证每个文件! (或使用 PGP - 对使用公钥的文件加密有更大的支持)
解密文件:
openssl smime -decrypt -binary -in encrypted.zip.enc -inform DER -out decrypted.zip -inkey private.key -passin pass:your_password
什么是什么:
-inform DER - 与上面的 -outform 相同 -inkey private.key - 你的私钥的文件名。应该是 PEM 格式,并且可以通过密码加密。 -passin pass:your_password - 你的私钥加密密码。 (passphrase arguments)【讨论】:
当我执行上面的命令时,我会得到一个带有所有 smime 选项的Usage smime [options] yourSslCertificate.pem ...
。
原来我必须做 -aes256
而不是 -aes-256-cbc
“该命令可以非常有效地加密任何文件,无论其大小或格式如何。”,但是在最后一段你承认它根本无法加密大文件......也许你应该当您的解决方案最终不适用于大文件时,不要对最终解决方案和所有文件做出如此自大的主张。您应该从解决方案的限制和范围开始,而不是结束。
是否有关于大于 600MB 文件的已知问题的错误报告?如果您只有可用的公钥,则无法验证加密文件。
我无法使用 public 密钥(如问题所要求的那样)使其工作。它需要证书。【参考方案3】:
我发现http://www.czeskis.com/random/openssl-encrypt-file.html 的说明很有用。
用您的示例中的文件名解释链接的站点:
生成对称密钥,因为您可以用它加密大文件
openssl rand -base64 32 > key.bin
使用对称密钥加密大文件
openssl enc -aes-256-cbc -salt -in myLargeFile.xml \ -out myLargeFile.xml.enc -pass file:./key.bin
加密对称密钥,以便您可以安全地将其发送给对方 人
openssl rsautl -encrypt -inkey public.pem -pubin -in key.bin -out key.bin.enc
销毁未加密的对称密钥,以免无人发现
shred -u key.bin
此时,您发送加密的对称密钥 (
key.bin.enc
) 和加密的大文件(myLargeFile.xml.enc
)到另一个 人然后其他人可以使用他们的私钥解密对称密钥 键使用
openssl rsautl -decrypt -inkey private.pem -in key.bin.enc -out key.bin
现在他们可以使用对称密钥来解密文件
openssl enc -d -aes-256-cbc -in myLargeFile.xml.enc \ -out myLargeFile.xml -pass file:./key.bin
你就完成了。其他人拥有解密文件,并且已安全发送。
【讨论】:
这是最好的解决方案。应该是排名靠前且被接受的答案【参考方案4】:您不能使用rsautl
直接加密大文件。相反,请执行以下操作:
-
使用
openssl rand
生成密钥,例如。 openssl rand 32 -out keyfile
使用openssl rsautl
加密密钥文件
使用openssl enc
加密数据,使用步骤 1 中生成的密钥。
将加密密钥文件与加密数据打包在一起。接收者需要使用他们的私钥解密密钥,然后使用生成的密钥解密数据。
【讨论】:
【参考方案5】:不建议使用 smime 加密非常大的文件,因为您可以使用 -stream 选项加密大文件,但由于硬件限制see: problem decrypting big files
而无法解密生成的文件如上所述,公钥加密不适用于加密任意长的文件。因此,以下命令将生成密码短语,使用对称加密加密文件,然后使用非对称(公钥)加密密码短语。注意:smime 包括使用主公钥和备用密钥来加密密码短语。备份公钥/私钥对将是谨慎的。
随机密码生成
将 RANDFILE 值设置为当前用户可访问的文件,生成 passwd.txt 文件并清理设置
export OLD_RANDFILE=$RANDFILE
RANDFILE=~/rand1
openssl rand -base64 2048 > passwd.txt
rm ~/rand1
export RANDFILE=$OLD_RANDFILE
加密
使用以下命令加密文件,使用 passwd.txt 内容作为密码和 AES256 到 base64(-a 选项)文件。使用非对称加密将 passwd.txt 加密到文件 XXLarge.crypt.pass 中,使用主公钥和备用密钥。
openssl enc -aes-256-cbc -a -salt -in XXLarge.data -out XXLarge.crypt -pass file:passwd.txt
openssl smime -encrypt -binary -in passwd.txt -out XXLarge.crypt.pass -aes256 PublicKey1.pem PublicBackupKey.pem
rm passwd.txt
解密
解密只是将 XXLarge.crypt.pass 解密为 passwd.tmp,将 XXLarge.crypt 解密为 XXLarge2.data,然后删除 passwd.tmp 文件。
openssl smime -decrypt -binary -in XXLarge.crypt.pass -out passwd.tmp -aes256 -recip PublicKey1.pem -inkey PublicKey1.key
openssl enc -d -aes-256-cbc -a -in XXLarge.crypt -out XXLarge2.data -pass file:passwd.tmp
rm passwd.tmp
已针对 >5GB 文件进行了测试..
5365295400 Nov 17 10:07 XXLarge.data
7265504220 Nov 17 10:03 XXLarge.crypt
5673 Nov 17 10:03 XXLarge.crypt.pass
5365295400 Nov 17 10:07 XXLarge2.data
【讨论】:
只是我的两分钱:我会放弃-a
以保持加密文件大小更小(无 Base64 编码)并添加 -pbkdf2
以获得更好的密钥派生(2021 年 openssl enc 抱怨关于简单-pass
)
smime
不是已经用对称密码加密,然后用 RSA 加密密钥吗?单独加密是否只是 smime 子命令对大文件无法正常工作的一种解决方法?【参考方案6】:
更多解释n. 'pronouns' m.
的回答,
公钥加密不适用于加密任意长的文件。一 使用对称密码(比如 AES)进行正常加密。每个 生成、使用和加密新的随机对称密钥的时间 使用 RSA 密码(公钥)。密文连同 加密的对称密钥被传输给接收者。收件人 使用他的私钥解密对称密钥,然后使用 用于解密消息的对称密钥。
有加密的流程:
+---------------------+ +--------------------+
| | | |
| generate random key | | the large file |
| (R) | | (F) |
| | | |
+--------+--------+---+ +----------+---------+
| | |
| +------------------+ |
| | |
v v v
+--------+------------+ +--------+--+------------+
| | | |
| encrypt (R) with | | encrypt (F) |
| your RSA public key | | with symmetric key (R) |
| | | |
| ASym(PublicKey, R) | | EF = Sym(F, R) |
| | | |
+----------+----------+ +------------+-----------+
| |
+------------+ +--------------+
| |
v v
+--------------+-+---------------+
| |
| send this files to the peer |
| |
| ASym(PublicKey, R) + EF |
| |
+--------------------------------+
以及解密流程:
+----------------+ +--------------------+
| | | |
| EF = Sym(F, R) | | ASym(PublicKey, R) |
| | | |
+-----+----------+ +---------+----------+
| |
| |
| v
| +-------------------------+-----------------+
| | |
| | restore key (R) |
| | |
| | R <= ASym(PrivateKey, ASym(PublicKey, R)) |
| | |
| +---------------------+---------------------+
| |
v v
+---+-------------------------+---+
| |
| restore the file (F) |
| |
| F <= Sym(Sym(F, R), R) |
| |
+---------------------------------+
此外,您还可以使用以下命令:
# generate random symmetric key
openssl rand -base64 32 > /config/key.bin
# encryption
openssl rsautl -encrypt -pubin -inkey /config/public_key.pem -in /config/key.bin -out /config/key.bin.enc
openssl aes-256-cbc -a -pbkdf2 -salt -in $file_name -out $file_name.enc -kfile /config/key.bin
# now you can send these files: $file_name.enc + /config/key.bin.enc
# decryption
openssl rsautl -decrypt -inkey /config/private_key.pem -in /config/key.bin.enc -out /config/key.bin
openssl aes-256-cbc -d -a -pbkdf2 -in $file_name.enc -out $file_name -kfile /config/key.bin
【讨论】:
最好使用-kfile /config/key.bin
而不是-k $(cat /config/key.bin)
,否则密码会在进程列表(任务管理器)中泄漏。【参考方案7】:
要使用openssl smime
安全地加密大文件 (>600MB),您必须将每个文件分成小块:
# Splits large file into 500MB pieces
split -b 500M -d -a 4 INPUT_FILE_NAME input.part.
# Encrypts each piece
find -maxdepth 1 -type f -name 'input.part.*' | sort | xargs -I % openssl smime -encrypt -binary -aes-256-cbc -in % -out %.enc -outform DER PUBLIC_PEM_FILE
为方便起见,以下是如何解密并将所有部分放在一起:
# Decrypts each piece
find -maxdepth 1 -type f -name 'input.part.*.enc' | sort | xargs -I % openssl smime -decrypt -in % -binary -inform DEM -inkey PRIVATE_PEM_FILE -out %.dec
# Puts all together again
find -maxdepth 1 -type f -name 'input.part.*.dec' | sort | xargs cat > RESTORED_FILE_NAME
【讨论】:
【参考方案8】:也许您应该查看这个 (How to encrypt data in php using Public/Private keys?) 问题的已接受答案。
它展示了如何使用 OpenSSL 的 S/mime 功能来做同样的事情而不需要手动处理对称密钥,而不是手动解决 RSA 的消息大小限制(或者可能是一个特征)。
【讨论】:
以上是关于如何使用公钥加密openssl中的大文件的主要内容,如果未能解决你的问题,请参考以下文章
如何从 .cer 中提取 RSA 公钥并使用 OpenSSL 将其存储在 .pem 中?
求助,在android端使用openssl生成的rsapublicKey解密的相关问题