【问题标题】:How to encrypt a large file in openssl using public key如何使用公钥加密openssl中的大文件
【发布时间】: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 位的密钥,但没有运气,同样的错误

【问题讨论】:

    标签: linux openssl


    【解决方案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 直接加密大文件。相反,请执行以下操作:

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

    【讨论】:

      【解决方案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 的消息大小限制(或者可能是一个特征)。

        【讨论】:

          猜你喜欢
          • 2011-10-29
          • 2011-03-30
          • 1970-01-01
          • 2020-03-15
          • 1970-01-01
          • 2012-04-28
          • 2013-06-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多