【问题标题】:Is std::random_device cryptographic secure?std::random_device 加密安全吗?
【发布时间】:2017-12-05 15:44:18
【问题描述】:

我看到很多人一起谈论安全和std::random_device

例如,here 第 22 张幻灯片。

根据cppreferencestd::random_device

std::random_device 是一个均匀分布的整数随机数生成器,它产生非确定性随机数。

它没有明确谈论安全性。

是否有任何有效的参考资料明确提到 std::random_device 对密码学来说是安全的?

【问题讨论】:

  • 我不能代表安全意义上的产品质量(security.stackexchange.com 可能是获得安全专家意见的更好去处)但random_device 允许下降如果非确定性生成器不可用,则返回确定性值,使其不那么有效。检查您的平台和工具链以获得全面支持。
  • std::random_device 没有提供任何保证 - 它的规范太弱以至于基本上没有作为“便携式”CSPRNG 使用。
  • 我认为 CPP 参考页面是错误的。根据P0205R0 - Allow Seeding Random Number Engines with std::random_device:"标准库提供了 std::random_device 类型(§ 26.5.6 [rand.device]),一个统一的随机数生成器(§ 26.5.1.3 [rand.req.urng])这应该(但不幸的是,不是必需的)产生一个非确定性的 unsigned int 类型的均匀分布整数序列。” 我的经验是,非确定性是一个棘手/困难的属性。

标签: c++ c++11 random cryptography


【解决方案1】:

不,因为 std::random_device 不是为此而设计的;它旨在生成随机数,而不是安全的。

在安全方面,随机性对于密钥生成很有用,但随机性并不是绝对需要的。例如,AES 不使用任何随机性,但在美国使用 AES-256 来加密绝密信息。

随机性和安全性交叉的一个领域是生成和使用随机密钥时;如果我能猜出种子并知道使用的随机协议,那么我很有可能可以使用相同的种子值来生成相同的“随机”值,从而生成相同的密钥。

std::random_device 将使用一个硬件模块(如硬件TPM),如果一个可用,否则它将使用操作系统作为RNG 的任何东西(如Windows 中的CryptGenRandom,或*nix 中的/dev/random系统),它甚至可能是一个 PRNG(伪随机数生成器),它可能会根据所使用的随机数算法生成相同的数字。附带说明:就像AES instruction set 被整合到芯片组中以加速加密和解密一样,hardware RNG's 有助于在算法转移到硬件时提供更大的熵池和更快的随机数生成。

因此,如果您在任何类型的加密密钥生成中使用 std::random_device,您需要了解正在部署的系统上使用的随机数生成器,否则您可能会发生冲突,从而导致您的加密系统可能容易受到重复密钥类型的攻击。

希望能有所帮助。

【讨论】:

【解决方案2】:

TL;DR:仅使用 std::random_device 为该库中定义的 PRNG 生成种子。否则,请使用 Crypto++、Bothan、OpenSSL 等加密库来生成安全随机数。


要了解为什么需要std::random_device,重要的是要根据定义它的上下文来查看它。

std::random_deviceset of classes and methods that are used to generate deterministic/pseudo random number sequences fast 的一部分。一个例子 - 也显示在幻灯片中 - 是 Mersenne twister 算法,它肯定不是加密安全的。

现在这一切都很好,但由于定义的算法都是确定性的,这可能不是用户可能追求的:他们想要一个不会一直产生相同流的快速随机数生成器。 种子不安全的 PRNG 需要某种熵源。这是std::random_device 发挥作用的地方,它用于播种梅森捻线机(如答案中提到的幻灯片所示)。

幻灯片显示 Mersenne twister 的速度差异约为 250 倍,而慢速系统提供了非确定性随机数生成器。这清楚地说明了为什么本地的、确定性的 PRNG 可以帮助加快随机数的生成。

还请注意,本地 PRNG 在多个线程中使用时不会减慢很多。当被多个线程访问时,系统生成器可能很快,但这肯定不是给定的。有时系统 RNG 甚至可能会阻塞或出现延迟或相关问题。


正如问题下方的 cmets 所述,std::random_device 的合同相当薄弱。如果系统生成器不可用,它会讨论使用“确定性”生成器。当然,在大多数桌面/服务器配置中,这样的设备(例如 /dev/random 或非阻塞 /dev/urandom 设备)可用的。在这种情况下,std:random_device 很可能会返回一个安全的随机数生成器。但是,您不能依赖在所有系统配置上都发生这种情况。

如果您需要一个相对较快的安全随机数生成器,我建议您使用 OpenSSL 或 Crypto++ 等加密库,而不是使用不安全且速度较慢的系统随机生成器。例如,OpenSSL 将使用系统随机生成器(以及其他熵源)来播种更安全的算法。

【讨论】:

猜你喜欢
  • 2017-06-28
  • 1970-01-01
  • 2014-06-15
  • 2020-06-12
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多