如何使用公钥在openssl中加密大文件


78

如何使用公共密钥加密大文件,以使只有拥有私有密钥的人才能解密该文件?

我可以将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位的键,没有运气,同样的错误

Answers:


82

公钥加密不适用于对任意长文件进行加密。人们使用对称密码(例如AES)进行常规加密。每次生成,使用并使用RSA密码(公钥)加密新的随机对称密钥。密文与加密的对称密钥一起传输到接收者。收件人使用其私钥解密对称密钥,然后使用对称密钥解密消息。

私钥永远不会共享,只有公钥用于加密随机对称密码。


1
但是非对称密码学的重点是防止共享私人机密,即使使用非对称密码学加密了密钥,这种方法仍会导致密钥的共享。使用非对称密码学(如RSA)对共享机密与对称算法进行加密是否有任何优势
Techno

3
@techno:您没有分享任何秘密。您生成一个一次性随机密钥,用它来加密一条消息,然后将其丢弃。与消息一起发送的密钥仅对该消息有效。
n。代词

1
是的,但是特定消息的一次性密钥是正确共享的吗?使用非对称加密(如RSA)对共享秘密和对称算法进行加密是否有任何优势
Techno 2013年

7
是。您还共享消息本身。如果您害怕共享密钥,也不要共享消息。
n。代词

1
@nm“严格来说,从性能角度来看,“公钥加密不是用于加密任意长文件的。” 使用接收者(或谁应该读取文件的人)的公共密钥对整个文件进行RSA加密还会带来其他弊端吗?
cyrus

73

安全和高度安全的解决方案,可以在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-选择的文件处理方法
  • -二进制使用安全文件过程。通常,输入消息会按照S / MIME规范的要求转换为“规范”格式,此开关会将其禁用。所有二进制文件(例如图像,声音,ZIP存档)都是必需的。
  • -aes-256-cbc-选择256位的AES密码进行加密(强)。如果未指定,则使用40位RC2(非常弱)。(支持的密码
  • -in plainfile.zip-输入文件名
  • -out crypto.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

什么是什么:

  • -通知DER与上面的相同
  • -inkey private.key私钥的文件名。该密码应为PEM格式,并可以通过密码加密。
  • -passin pass:您的密码-您的私钥加密密码。(密码参数

1
当我执行上面的命令时,我得到了Usage smime [options] yourSslCertificate.pem ...所有smime选项。
Brian Armstrong 2014年

4
原来我不得不做,-aes256而不是-aes-256-cbc
Brian Armstrong

9
“该命令可以非常有效地对任何文件进行强力加密,无论其大小或格式如何。”,但是在最后一段,您承认它根本无法加密大文件。最终所有解决方案都不适用于大文件。您应该从解决方案的局限性和范围开始,而不是从解决方案开始。
2014年

2
是否存在有关大于600MB大型文件的已知问题的错误报告?如果只有公共密钥可用,则无法验证加密文件。
Sampo

这是危险的解决方案。它导致大文件(> 2GB)的信息丢失。您需要先分割大文件
l0pan'1

30

您无法使用来直接加密大型文件rsautl。相反,请执行以下操作:

  1. 使用生成密钥openssl rand,例如。openssl rand 32 -out keyfile
  2. 使用加密密钥文件 openssl rsautl
  3. 使用openssl enc步骤1中生成的密钥,使用加密数据。
  4. 将加密的密钥文件与加密的数据打包在一起。接收者将需要使用其私钥解密密钥,然后使用生成的密钥解密数据。

27

我在以下位置找到了说明 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

这样就完成了。另一个人拥有解密的文件,并且已安全发送。


1
这是最好的解决方案。应该是排名最高且被接受的答案
国王

22

不建议使用smime加密非常大的文件,因为您可以使用-stream选项加密大文件,但由于硬件限制,不能解密生成的文件 请参见:解密大文件时问题

如上所述,公钥加密不是用于加密任意长文件。因此,以下命令将生成一个密码,使用对称加密对文件进行加密,然后使用非对称(公用密钥)对密码进行加密。注意: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

3

为了安全地加密大文件(> 600MB),openssl smime您必须将每个文件分成小块:

# 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

3

在有关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 -k $(cat /config/key.bin)

# now you can send this 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 -in $file_name.enc -out $file_name -k $(cat /config/key.bin)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.