【问题标题】:openssl smime: aes vs rsa - which one encrypts?openssl smime:aes vs rsa - 哪个加密?
【发布时间】:2016-01-30 10:25:16
【问题描述】:

当我想加密大文件时,我找到了以下命令:

openssl smime -encrypt -binary -aes-256-cbc \
-in large_file.img -out large_file.img.dat \
-outform DER \
public-rsa2048.pem

私钥/公钥是这样创建的:

openssl req -x509 -nodes -newkey rsa:2048 \
-keyout private-rsa2048.pem -out public-rsa2048.pem

所以我使用aes-256-cbs 以及rsa-key。

  1. 现在谁负责加密?
  2. 哪一项会影响性能以及如何影响性能?

如果我增加/降低公钥(rsa512 与 rsa4096),这会影响性能吗?

如果我选择不同的aes 算法,这也会影响性能吗?

有人可以为这件事带来一些启示吗?

  1. 还有其他加密大文件的方法吗?

【问题讨论】:

  • Hybrid encryption,但无论哪种方式,这都不是与编程相关的问题。因此,它是题外话。
  • 我可以看到这与编程有关,因为许多库/应用程序与 OpenSSL 加密的数据进行交互,并且了解命令行工具如何执行这些操作是相关的。

标签: encryption openssl aes rsa smime


【解决方案1】:

使用openssl smime 命令加密数据会以这样一种方式对其进行加密,以便收件人using email 可以接收和解密。这意味着它使用代表各种实体(发送者、接收者)并包含与这些实体唯一关联的密钥的证书来对包含的数据进行签名、加密、解密和验证签名。

正如 Artjom 在他们的评论中指出的那样,使用了混合密码系统。这意味着使用symmetricasymmetric 加密算法的组合,因为它们各有优缺点。与非对称加密(如 RSA)相比,对称加密(如 AES)速度极快。但是,AES/CBC 仅提供机密性,不提供完整性、身份验证或不可否认性。非对称加密可以提供完整性、身份验证和不可否认性。非对称加密对它可以加密的数据量也有相当低的限制(例如,一个 RSA-4096 位密钥一次最多可以加密 446 个字节)。通过结合这两种方法,我们可以发挥各自的优势并减轻对方的弱点。

在这种情况下,让我们的消息是M。生成长度为 256 位的 AES/CBC 密钥 Kaes 并用于加密原始数据,使得密文 CC = E(Kaes, M)。然后使用接收者的公钥KrpubKaes 加密为C' = E(Krpub, Kaes)。加密这少量数据的成本相对较低,即使我们使用的是昂贵的操作。

注意 在加密临时会话密钥之前,可能会使用发件人的私钥 Kspriv 对其进行签名,除非数字签名被禁用。我不是 100% 确定 S/MIME,但这就是 PGP 的工作方式,因为当发送给多个收件人时,使用n 收件人的公钥加密会话密钥然后用发件人的私钥 O(2n)O(n+1) (不是真正的 Big-O 表示法,但对于传达这一点很有效)。无论接收者如何,会话密钥的签名都是相同的,因为它仅取决于发送者的私钥。

现在剩下的就是连接加密的会话密钥C' 和密文C 并将它们传输给接收者。在真实的 S/MIME 消息中,还会传输有关发送者公钥的识别信息,以便于签名验证。接收者解析完整的加密消息,使用接收者的私钥Krpriv解密会话密钥,然后使用会话密钥Kaes解密密文C

但是,对于您的情况,所有这些似乎都有些过头了。如果您不需要与电子邮件通信系统集成而只是尝试加密大文件以进行存储,openssl 还提供了一个简单的enc 命令。您可以按如下方式使用它:

基于密码的加密: $ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc -k thisIsABadPassword

-k 允许您在从中派生密钥的命令行上输入密码。 OpenSSL 使用确定性密钥派生函数 (KDF)(实际上是 key, iv = MD5(password||salt))。您可以在末尾使用-p 运行此命令,以将密钥、盐和IV 打印到控制台。 IV 确定性地从密码和盐中派生。推荐使用像 PBKDF2 这样的 KDF,但 OpenSSL 中的库函数由于某种原因不会将其暴露给命令行工具。

警告您可以运行此命令并指定 -nosalt 以跳过盐生成,但不建议这样做,因为它会使已经非常弱的 KDF 变得更弱。

密钥加密: $ openssl enc -aes-256-cbc -in large_plain_file.dmg -out large_encrypted_file.enc K 0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210 -IV 0123456789ABCDEFFEDCBA9876543210

使用提供的实际密钥和 IV 运行。密钥为 32 字节(256 位),IV 为 16 字节(一个 AES 块的大小)。

要解密数据,请运行带有-d 标志的命令:

$openssl enc -aes-256-cbc -d -in large_encrypted_file.dmg -out large_decrypted_file.enc

这对您来说会更简单(无需证书/密钥对)并且更快(无需 RSA 加密)。

所有这一切都需要记住的是,如果您在命令调用中提供密码/密钥,密码/密钥将保留在终端历史记录中。在没有-k-K 的情况下运行将提示在安全提示中输入密码。或者使用-pass 从环境变量、文件或文件描述符中读取。


更新以明确解决原始问题:

  1. AES 密钥负责加密数据。 RSA 密钥用于加密 AES 密钥。
  2. 两者都会影响性能。 AES 密钥加密的数据要多得多,但比 RSA 加密要快得多。
    • 是的,更改 RSA 密钥的大小会影响性能(密钥大小越大越慢),但对于大文件,这不太可能成为性能的限制因素。
    • 是的,更改 AES 操作模式可能会对性能产生重大影响。 AES/CBC、AES/OFB 和 AES/CFB 的相似之处在于它们是串行操作(取决于一个块操作的结果进行下一个块操作),但 AES/CTR 作为流密码运行并且可以并行化为提供加密和解密。
  3. 见上面的答案。

【讨论】:

  • 感谢您对我的问题的这个非常详细的回答。有点题外话:我想自动进行加密(通过 cron),但它不应该通过ps aux 泄露任何密码,我也不想将密码存储在加密机器的任何地方。所以我想我将不得不坚持smime 选项。
  • 有一个标志可以从文件中读取密码(第一行)。这样您就可以从命令行历史记录中隐藏密码。查看openssl enc 文档页面。
  • 对不起,错过了关于不将密码存储在机器上的部分。
  • 另外,即使它从历史记录中隐藏,它也会在ps aux 中可见,尽管它是从文件中读取的?
  • 我相信从ps aux 可以看到文件的路径,但是如果拥有文件权限,您应该能够锁定文件,这样非特权用户就无法查看它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 2018-11-29
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 2020-10-14
相关资源
最近更新 更多