为什么 OpenSSH 不推荐使用 DSA 密钥

信息安全 SSH RSA 打开sh dsa
2021-09-07 05:26:51

有一个关于 SSH 身份验证密钥的 RSA 与 DSA的问题,询问哪个密钥更好。基本上所有答案都更倾向于 RSA 而不是 DSA,但并没有真正说明 DSA 会在某种程度上不安全。

但是现在 DSA 已被 OpenSSH 弃用,后来将被完全删除:https ://www.gentoo.org/support/news-items/2015-08-13-openssh-weak-keys.html

该信息指出:

从 OpenSSH 7.0 版本开始,由于 ssh-dss 密钥的继承弱点,默认情况下在运行时禁用了对它们的支持。如果您依赖这些密钥类型,您将不得不采取纠正措施,否则将面临被锁定的风险。

您最好的选择是使用强算法(如 rsa 或 ecdsa 或 ed25519)生成新密钥。RSA 密钥将为您提供与其他客户端/服务器的最大可移植性,而 ed25519 将为您提供 OpenSSH 的最佳安全性。

是什么让 DSA 密钥本身就很弱?

3个回答

这是一个很好的问题。OpenSSH专用页面仅显示:

OpenSSH 7.0 及更高版本同样禁用 ssh-dss (DSA) 公钥算法。它也很弱,我们建议不要使用它。

这并不比公告中的“继承弱点”更详细。我没有找到任何关于这些弱点的公开解释,除了一些未经证实的关于“最近发现”的狡辩。因此,是时候进行一些调查了。

在 OpenSSH-6.9p1(Ubuntu 15.10 包)的源代码中,对于密钥生成工具ssh-keygen,我发现了这段非凡的代码:

    maxbits = (type == KEY_DSA) ?
        OPENSSL_DSA_MAX_MODULUS_BITS : OPENSSL_RSA_MAX_MODULUS_BITS;
    if (*bitsp > maxbits)
            fatal("key bits exceeds maximum %d", maxbits);
    if (type == KEY_DSA && *bitsp != 1024)
            fatal("DSA keys must be 1024 bits");

OPENSSL_DSA_MAX_MODULUS_BITS是 OpenSSL 标头中的一个常量,将其定义为 10000。因此,前四行检查请求的密钥大小,在生成时,实际上可以由密钥生成过程处理。但是,接下来的两行基本上是说:“不管上面的测试,如果 key 是 DSA 并且大小不是 1024,niet。”

这 6 行代码本身就是一个明确的迹象,表明开发该代码的人在密钥大小方面并不完全同意自己的看法。这段代码可能是由不同的人逐步组装而成的。“1024”的来源可以追溯到实际的DSA标准(称为“DSS”作为“数字签名标准”),FIPS 186-4. 该标准经过多次修订。在其第一个版本中,DSA 被要求使用大小在 512 和 1024 位之间的模数(并且应该是 64 的倍数,大概是为了简化实施者的任务)。后来的版本承认技术能力和数学进步的增加,并禁止了 1024 位以外的任何大小。现代版本的 FIPS 186(第四次修订,截至 2016 年初)允许模数的大小为 1024、2048 或 3072 位。

因此可以推测,ssh-keygen拒绝使用与 1024 位不同的模数大小是因为有人在某个时候阅读了当时的 FIPS 186 版本,该版本正是强制要求的,而ssh-keygen当 FIPS 标准被修改时,没有人愿意更新。不管这个壮观的编程精神分裂症是如何产生的,原始结果是,当今使用的大多数(如果不是全部)DSA 类型的 SSH 密钥都依赖于 1024 位模数。

下一个难题是Logjam 攻击Logjam 基本上是关于注意到当客户端和服务器同意使用弱加密时,它们可能会受到攻击。这是对 SSL/TLS 的攻击,而不是 SSH。然而,Logjam 文章并没有停留在(正确地)抨击 SSL/TLS 实现为 DH 使用 512 位模数;它还为“国家级对手”提供了一些谈话空间。那部分主要是说一些已知的东西,即打破离散对数模1024位模数(允许同时打破DH和DSA的东西)现在非常昂贵,但并非不可能 关于我们目前对该问题的了解和可用技术(类似于破解 RSA-1024,与破解 2048 位 DH 或 DSA 完全不同,这超出了当前地球资源的可行性)。

在听者的耳朵里,这一切听起来就像“天哪,我们都被 NSA 盗版了!” 围绕 Logjam 问题(这是非常真实的)的宣传随之而来的是对 1024 位 DSA 密钥主题的大量歇斯底里,包括在 SSH 中使用它们时。

额外的一点是,使用 DSA 需要为每个签名生成一个新的随机值,并且该值的生成质量至关重要。一些实施失败了,导致私钥泄露(特别是对于一些“比特币钱包”)。DSA 的这一特性与其椭圆曲线版本 ECDSA 共享。可以被修复但它灌输了这样一种想法,即 DSA 签名可能很难正确完成(ECDSA 签名同样如此,但椭圆曲线很酷,没有人想禁止它们)。

这些参数综合起来解释了禁令。这可以看作是 OpenSSH 开发人员在他们的安全概念上积极主动并准备强迫用户使用强加密的一个例子。另一种看待相同决策顺序的方式是,OpenSSH 开发人员在某些时候犯了严重错误,因为对 FIPS 186 的阅读不佳,然后试图用相当于在海上倾倒不方便丈夫的尸体来掩盖它。

请注意,破解您的 DSA 密钥将允许攻击者冒充您,但不能解密记录的会话。虽然可以说切换到 ECDSA 密钥在某些时候是一个好主意(它节省了一点带宽和 CPU),但没有密码分析的紧迫性。您仍然必须这样做,否则您可能会被锁定在服务器之外,因为某些打包程序对弃用策略过于热心。

https://bugzilla.mindrot.org/show_bug.cgi?id=1647有将 DSA 密钥限制为 1024 位的原因,但基本上:

  • RFC4253 第 6.6 节要求 SHA1 哈希(160 位)用于 ssh-dss(即 DSA)身份验证。
  • FIPS 186-3 第 4.2 节要求 DSA 密钥 >1024 位以使用比 160 位更强的散列。
  • 满足两者的唯一方法是只允许 1024 位密钥。

186-3(和 -4)4.2 说“通常不应该”使用比 L,N 弱的散列

那部分说

通常不应使用提供低于 (L, N) 对的安全强度的散列函数。

上面说

本标准规定了 L 和 N 对的以下选择(p 和 q 的位长,
分别):
L = 1024,N = 160
L = 2048,N = 224
L = 2048,N = 256
L = 3072,N = 256
联邦政府实体*应*使用以下一项或多项生成数字签名
这些选择。

[编辑:我去(重新)阅读了 NIST SP.800-57。第 5.6.1 节。即使允许违反 FIPS 186-3 中的建议并使用具有更大 DSA 密钥的 SHA-1,它也不会变得更强大,因为它仍然会受到 SHA-1 强度的限制]

OpenSSH 在 rfc8338 发布前两年实现了新的 pkalgs rsa-sha2-256 和 rsa-sha2-512

这些是在作为 RFC 发布之前三年的标准草案。

事实上,最初有一个 dsa-sha2-256 在符合 FIPS 186-3 的同时允许 2k 和 3k DSA 密钥,但很快就被放弃了这种方案还需要软件升级。