OpenSSL 1.1.1b 警告:在解密使用 OpenSSL 1.1.0g 加密的文件时,使用 -iter 或 -pbkdf2 会更好

OpenSSL 1.1.1b 警告:在解密使用 OpenSSL 1.1.0g 加密的文件时,使用 -iter 或 -pbkdf2 会更好

今天我得到了这个警告在更新一些软件包后,Cygwin 中的 OpenSSL 发布了,我相信openssl其中包括:

*** 警告:使用已弃用的密钥派生。
使用-iteror-pbkdf2会更好。


Cygwin 中使用的 OpenSSL 版本曾是:

OpenSSL 1.1.1b  26 Feb 2019

这是在解密我在 BluRay 上创建的备份时发生的Linux 薄荷 19.1,其中 OpenSSL 版本是明显老了:

OpenSSL 1.1.0g  2 Nov 2017

用于加密和解密的命令(只需添加-d到末尾)是:

openssl enc -aes-256-cbc -md sha256 -salt -in "$InputFilePath" -out "$OutputFilePath"

此警告是什么意思?我可以采取什么措施来避免在将来的备份中出现这种情况吗?

答案1

比较 OpenSSL 的两个主要版本和最新版本的 Synopsys,让我引用一下手册页。

开放式SSL1.1.0

openssl enc -ciphername [-help] [-ciphers] [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md digest] [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-engine id]

开放式SSL1.1.1

openssl enc -cipher [-help] [-ciphers] [-in filename] [-out filename] [-pass arg] [-e] [-d] [-a] [-base64] [-A] [-k password] [-kfile filename] [-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md digest] [-iter count] [-pbkdf2] [-p] [-P] [-bufsize number] [-nopad] [-debug] [-none] [-rand file...] [-writerand file] [-engine id]

显然有一些更大的差异,即考虑到这个问题,1.1.0 中缺少这两个开关:

  • pbkdf2

  • iter


你现在基本上有两个选择。忽略警告或将加密命令调整为:

openssl enc -aes-256-cbc -md sha512 -pbkdf2 -iter 1000000 -salt -in InputFilePath -out OutputFilePath

这些开关的位置:

  • -aes-256-cbc就是你应该用于最大程度的保护或 128 位版本;3DES(三重 DES)不久前就被废弃了,参见三重 DES 已于 2017 年被 NIST 弃用,而 AES 被所有现代 CPU 加速很多;你可以简单地验证你的CPU是否有AES-NI指令集例如使用grep aes /proc/cpuinfo;赢,赢

  • -md sha512 与 SHA-256 相比,SHA-2 函数系列的速度更快一些虽然它可能更安全一些;赢,赢,但这可能会随着新的SHA指令集在现代CPU中

  • -pbkdf2: 使用PBKDF2(基于密码的密钥导出函数2)算法

  • -iter 1000000覆盖密码的默认迭代次数(10000),引用手册页:

    在派生加密密钥时对密码使用给定的迭代次数。高值会增加暴力破解生成文件所需的时间。此选项允许使用 PBKDF2 算法来派生密钥。


迭代的默认值没有记录,但在apps/enc.c文件中指定,如下所示:

case OPT_PBKDF2:
    pbkdf2 = 1;
    if (iter == 0)
        iter = 10000;
    break;

-d只需在原始命令行末尾添加开关即可进行解密。

答案2

最近我安装了最新版本的cygwin。 “openssl”开始发出警告:

*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.

所以现在我使用以下内容进行加密:

openssl aes-256-cbc -salt -pbkdf2 -in name -out name.aes

以及以下用于解密:

openssl aes-256-cbc -d -salt -pbkdf2 -in name.aes -out name

答案3

听起来 OpenSSL 终于在至少 6 年之后承认该enc命令存在一些相当严重的缺陷(他们自己的手册页称它们为“bug”)。也许它们现在正在修复,但如果您的数据非常重要,为什么不使用(相对)更安全的工具,例如GnuPG反而?您也不一定需要使用公钥加密,gpg 也可以进行传统的(仅密码/密钥文件)加密。

这是摘录自我的另一个答案强调基础知识:

开放式SSL应该能够完成 gpg 所做的所有相同的事情(OpenSSL 自 1998 年以来就已存在,但如果版本号有什么意义的话,它在 2010 年达到了版本 1),但很容易犯错误,从而大大降低安全性。并从security.stackexchange.com 上的这篇文章(2013 年 1 月起)和另一个对于 287K 信誉用户来说,该openssl enc命令可能有一些不足之处:

OpenSSL 使用的加密格式是非标准的:它是“OpenSSL 所做的”,如果 OpenSSL 的所有版本都趋于彼此一致,那么除了 OpenSSL 源代码之外,仍然没有描述这种格式的参考文档。标头格式相当简单:

magic value (8 bytes): the bytes 53 61 6c 74 65 64 5f 5f
salt value (8 bytes)

因此,固定的 16 字节标头以字符串“Salted__”的 ASCII 编码开头,后面是盐本身。就这样 !没有注明加密算法;你应该自己跟踪这一点。

密码和盐转换为密钥和 IV 的过程没有记录,但查看源代码表明它调用了 OpenSSL 特定的EVP_BytesToKey()函数,它使用自定义密钥导出函数一些重复的散列。这是一个非标准且未经充分审查的构造 (!),它依赖于信誉可疑的 MD5 哈希函数 (!!);该函数可以在命令行上更改无证的 -md旗帜 (!!!); “迭代计数”由命令设置enc1并且无法更改(!!!)。这意味着密钥的前 16 个字节将等于MD5(密码||盐),就是这样。

这实在是太弱了!任何知道如何在 PC 上编写代码的人都可以尝试破解这种方案,并且每秒能够“尝试”数千万个潜在密码(使用 GPU 可以实现数亿个密码)。如果您使用“openssl enc”,请确保您的密码具有非常高的熵!(即高于通常推荐的值;至少目标为 80 位)。或者,最好根本不使用它;相反,寻找更强大的东西(GnuPG,在对密码进行对称加密时,使用更强的 KDF 以及底层哈希函数的多次迭代)。

man enc甚至在“BUGS”下也有这个:

应该有一个选项允许包含迭代计数。

评论之一第一篇文章甚至提到这些问题已经存在了近10年了......

这个迭代计数问题确实很麻烦。差不多 10 年前,我制作了一个“加密”perl 脚本,其功能与“openssl enc”基本相同,但使用迭代 PBKDF2 哈希。 ict.griffith.edu.au/anthony/software#encrypt 它将解密加盐的“openssl enc”文件,但使用 PBKDF2 重新加密。我希望 OpenSSL 文件加密现在已经有所改进! –安东尼2 月 7 日 5:05

这是一个使用 gpg 进行对称加密的示例
简而言之:

gpg --symmetric --cipher-algo AES256 --output file.gpg file.txt

gpg --decrypt --output file.txt file.gpg

相关内容