如何安全地生成随机数
创始人
2024-03-01 22:17:55
0

使用 urandom

使用 urandom!使用 urandom!使用 urandom

使用 urandom!使用 urandom!使用 urandom

但对于密码学密钥呢?

仍然使用 urandom

为什么不是 SecureRandom、OpenSSL、havaged 或者 c 语言实现呢?

这些是用户空间的 CSPRNG(伪随机数生成器)。你应该用内核的 CSPRNG,因为:

  • 内核可以访问原始设备熵。
  • 它可以确保不在应用程序之间共享相同的状态。
  • 一个好的内核 CSPRNG,像 FreeBSD 中的,也可以保证它播种之前不给你随机数据。

研究过去十年中的随机失败案例,你会看到一连串的用户空间的随机失败案例。Debian 的 OpenSSH 崩溃?用户空间随机!安卓的比特币钱包重复 ECDSA 随机 k 值?用户空间随机!可预测洗牌的赌博网站?用户空间随机!

用户空间的生成器几乎总是依赖于内核的生成器。即使它们不这样做,整个系统的安全性也会确保如此。但用户空间的 CSPRNG 不会增加防御深度;相反,它会产生两个单点故障。

手册页不是说使用 /dev/random 嘛?

这个稍后详述,保留你的意见。你应该忽略掉手册页。不要使用 /dev/random/dev/random/dev/urandom 之间的区别是 Unix 设计缺陷。手册页不想承认这一点,因此它产生了一个并不存在的安全顾虑。把 random(4) 中的密码学上的建议当作传说,继续你的生活吧。

但是如果我需要的是真随机值,而非伪随机值呢?

urandom 和 /dev/random 提供的是同一类型的随机。与流行的观念相反,/dev/random 不提供“真正的随机”。从密码学上来说,你通常不需要“真正的随机”。

urandom 和 /dev/random 都基于一个简单的想法。它们的设计与流密码的设计密切相关:一个小秘密被延伸到不可预测值的不确定流中。 这里的秘密是“熵”,而流是“输出”。

只在 Linux 上 /dev/random 和 urandom 仍然有意义上的不同。Linux 内核的 CSPRNG 定期进行密钥更新(通过收集更多的熵)。但是 /dev/random 也试图跟踪内核池中剩余的熵,并且如果它没有足够的剩余熵时,偶尔也会罢工。这种设计和我所说的一样蠢;这与基于“密钥流”中剩下多少“密钥”的 AES-CTR 设计类似。

如果你使用 /dev/random 而非 urandom,那么当 Linux 对自己的 RNG(随机数生成器)如何工作感到困惑时,你的程序将不可预测地(或者如果你是攻击者,非常可预测地)挂起。使用 /dev/random 会使你的程序不太稳定,但这不会让你在密码学上更安全。

这是个缺陷,对吗?

不是,但存在一个你可能想要了解的 Linux 内核 bug,即使这并不能改变你应该使用哪一个 RNG。

在 Linux 上,如果你的软件在引导时立即运行,或者这个操作系统你刚刚安装好,那么你的代码可能会与 RNG 发生竞争。这很糟糕,因为如果你赢了竞争,那么你可能会在一段时间内从 urandom 获得可预测的输出。这是 Linux 中的一个 bug,如果你正在为 Linux 嵌入式设备构建平台级代码,那你需要了解它。

在 Linux 上,这确实是 urandom(而不是 /dev/random)的问题。这也是 Linux 内核中的错误。 但它也容易在用户空间中修复:在引导时,明确地为 urandom 提供种子。长期以来,大多数 Linux 发行版都是这么做的。但不要切换到不同的 CSPRNG。

在其它操作系统上呢?

FreeBSD 和 OS X 消除了 urandom 和 /dev/random 之间的区别;这两个设备的行为是相同的。不幸的是,手册页在解释为什么这样做上干的很糟糕,并延续了 Linux 上 urandom 可怕的神话。

无论你使用 /dev/random 还是 urandom,FreeBSD 的内核加密 RNG 都不会停摆。 除非它没有被提供种子,在这种情况下,这两者都会停摆。与 Linux 不同,这种行为是有道理的。Linux 应该采用它。但是,如果你是一名应用程序开发人员,这对你几乎没有什么影响:Linux、FreeBSD、iOS,无论什么:使用 urandom 吧。

太长了,懒得看

直接使用 urandom 吧。

结语

ruby-trunk Feature #9569

现在,在尝试检测 /dev/urandom 之前,SecureRandom.random_bytes 会尝试检测要使用的 OpenSSL。 我认为这应该反过来。在这两种情况下,你只需要将随机字节进行解压,所以 SecureRandom 可以跳过中间人(和第二个故障点),如果可用的话可以直接与 /dev/urandom 进行交互。

总结:

/dev/urandom 不适合用来直接生成会话密钥和频繁生成其他应用程序级随机数据。

GNU/Linux 上的 random(4) 手册所述……

感谢 Matthew Green、 Nate Lawson、 Sean Devlin、 Coda Hale 和 Alex Balducci 阅读了本文草稿。公正警告:Matthew 只是大多同意我的观点。


via: https://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/

作者:Thomas & Erin Ptacek 译者:kimii 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

给AI玩具设一道隐私“防火...
江德斌 据6月9日央视网报道,从能讲故事的智能玩偶,到可情感交互的...
2025-06-13 07:14:10
某租房平台AES加密解密
本次逆向站点aHR0cHM6Ly93d3cubWFvbWFvenU...
2025-06-01 00:48:12
CentOS上安装或更新O...
CentOS与OpenSSL 1.0:关键技术与安全实践探讨 在服...
2025-03-14 07:40:24
“黑箱”,AI开始自言自语...
文丨陆弃 近日,一段由人工智能(AI)进行的对话视频在网络上引发了...
2025-02-26 15:49:28
外媒:一段AI对话视频在网...
【环球网报道】据《福布斯》等美国媒体2月25日报道,近日,一段两个...
2025-02-26 14:50:31
不重复的随机数存储在变量中
以下是一个解决方法的示例代码:import randomdef g...
2025-01-12 13:01:37

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
从 Yum 更新中排除特定/某... 作为系统更新的一部分,你也许需要在基于 Red Hat 系统中由于应用依赖排除一些软件包。如果是,如...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...
如何检查你的 Linux 系统... 不知道在使用哪个初始化系统?以下是方法。每个主流 Linux 发行版(包括 Ubuntu、Fedor...