RNG 在 PGP 签名中发挥作用吗?

信息安全 pgp 虚拟化 随机的
2021-08-28 18:24:25

我们有一个构建和 PGP 签名软件版本的 Jenkins 系统,我们正在考虑将签名组件移动到一个隔离的 VM,而不是将其作为整个构建器基础架构的一部分运行——以便更好地将私钥与所有其他相对公共的运动部件。

一些开发人员反对使用虚拟机,因为虚拟机通常很少有良好熵的来源,因此通常不适合密码学。我想提出一个相反的论点,因为我们将使用在其他地方生成的 PGP 密钥,所以将在该 VM 上完成的唯一加密操作根本不会依赖 RNG。我对 PGP 签名过程的理解是它计算一个 sha1/sha2 哈希(不使用 RNG),然后使用私钥计算签名(不使用 RNG)。

那是对的吗?或者我是否遗漏了一些会使强 RNG 成为仅 PGP 签名但从不 PGP 加密的系统的要求?

2个回答

不幸的是,以前对这个问题的回答不仅错误而且非常危险

虽然数字签名通常涉及散列函数,这在本质上是确定性的,但您应该注意,数字签名不仅仅是一个简单的散列它们涉及公钥加密,其使用方式保证只有私钥的合法所有者才能签署某些东西。有很多数字签名算法,在实践中被广泛使用的有以下几种:

至少 DSA、ECDSA 和 ElGamal 在设计上确实需要随机数重复使用随机数,可以导致私钥的恢复。这非常简单,任何对该主题感兴趣的人都可以通过几个非常基本的方程式来理解。

过去曾发生过各种各样的攻击来说明这一事实。可能最普遍的例子是 PlayStation 3 的黑客攻击,它为我们带来了以下 xkcd 漫画:

https://xkcd.com/221/

另一方面,使用RSA并不是那么容易。“教科书”RSA 不需要随机数。然而,攻击者有可能对简单的 RSA 实现进行存在性伪造攻击。因此,在实践中使用了可能以概率方式运行的修改方案。基本思想是有效签名必须满足某种形式。一种这样的标准称为概率签名协议 (PSS)

GPG 已实施上述所有方案。到目前为止,RSA 似乎是大多数系统的默认设置。RFC 4880声明 OpenPGP 使用EMSA-PKCS1-v1_5,这是一种确定性填充方案,并且确实不需要随机数。

所以,本质上的,数字签名确实需要随机数,使用虚拟机来完成这些任务可能是个坏主意。至少这是需要有意识地思考的事情。

在 OpenPGP 中使用 RSA 签名是确定性的,因此不需要您正确描述的随机源。对要签名的数据进行散列是确定性的,只要不填充随机种子(请参阅@Karol Babioch 的答案,了解为什么要这样做的详细信息,对散列进行签名也是如此。

所涉及部分的详细讨论:

您可以尝试使用faketime将时间设置为某个固定时间(不要使用密钥创建时间之前的日期):

$ faketime '@2147483647' gpg --sign --output - somefile  | gpg --print-md SHA256
93C7E062 151311F2 822FBBBF FC4B061A C8F31A1A 54FDA558 61A9C964 B5107CD4

在不伪造时间的情况下,随着时间戳的变化,您将收到不同的哈希值。

对于其他算法,请参阅@Karol Babioch 的回答。这场辩论的结论是:使用 RSA 登录虚拟机或其他低熵设备(一些嵌入式盒子、路由器……),因为它不依赖于随机性;但最好从其他地方导入密钥对。


另一方面,使用 RSA加密也需要随机数:公共/私有加密仅用于加密分组密码密钥,并且可能会应用一些填充。

显然,创建一个新的 OpenPGP 密钥对也需要随机性。