【问题标题】:random.randint to generate cryptographically secure keysrandom.randint 生成加密安全密钥
【发布时间】:2017-08-11 20:55:06
【问题描述】:

此链接中的文档说 randint 不应该用于生成加密密钥: https://docs.python.org/2/library/random.html

我试图了解攻击者为什么以及如何基于这样的密钥破解密码系统。

【问题讨论】:

  • 没错,你应该使用秘密模块

标签: python random python-cryptography


【解决方案1】:

Python 使用伪随机数生成器 (prng) 来创建程序使用的“随机”数。这些数字是由看似随机的数学算法生成的。 python 使用的算法是 Mersenne Twister。如文档中所述:

Python 使用 Mersenne Twister 作为核心生成器。它产生 53 位精度浮点数,周期为 2**19937-1。底层证券 C 中的实现既快速又线程安全。梅森捻线机 是最广泛测试的随机数生成器之一 存在。但是,由于是完全确定性的,因此不适合 用于所有目的,并且完全不适合加密 目的。

如前所述,算法的目的是既要快速又尽可能“随机”。注意第二句提到了算法的“周期”。因为计算机不是完美的,只有有限的内存,它们只能根据这个算法产生这么多的“随机”数字。周期是机器在开始重复之前可以达到的 prng 状态数 (https://softwareengineering.stackexchange.com/questions/273105/why-is-the-period-of-a-pseudorandom-number-generator-important)。再加上这一点,python 会根据您运行程序的机器的内部特性来决定使用什么“状态”或使用什么“种子”。 (请参阅 random.seed 上的文档)

random.seed(a=None)¶ 初始化随机数的内部状态 生成器。

没有或没有来自当前时间或操作的参数种子 系统特定的随机源(如果可用)(参见 os.urandom() 功能了解可用性的详细信息)。

因此,攻击者可以使用蛮力和运行应用程序的机器的基本知识重新创建和确定程序中 prng 的顺序和未来状态。我绝不是伪随机数生成算法方面的专家,但希望这能让你掌握这个主题:)

【讨论】:

  • '由于“随机”数字的概念在现实世界中并不真正存在......'很多人会不同意你的观点。作为一名专业的统计学家,我就是其中之一。我的许多量子物理学家朋友也会质疑你的说法。我是否可以强烈建议您删除它,因为您的帖子的其余部分不需要它?
  • @pjs 感谢您的反馈,非常感谢!我当然不是量子物理学专家,所以我不会质疑你或你的物理学家同行。您能否提供一个简短的解释或链接来支持您的主张?如果将来有人质疑我的意见,我很乐意为您的建议提供证据。
  • 我不是物理学家,我是统计学家。根据我们的标准,任何无法确定地预测的事物都被称为随机性,而当前未知且未先验确定的结果可以/应该被建模为随机性。对于物理学家的观点,请参阅nature.com/nature/journal/v464/n7291/edsumm/e100415-06.html。另外,看看海森堡的不确定性原理,它证明你不能同时确定一个物体的位置和速度:abyss.uoregon.edu/~js/21st_century_science/lectures/lec14.html
  • 底线 - 一旦你承认系统状态的任何方面是不可知的,那么即使系统的行为是机械的,后续状态也无法确定地预测。大多数 PRNG 不能用于加密的原因是,通过足够长的观察集,可以确定地推断出它们的内部状态。
  • 另一个您可能会感兴趣的链接:askamathematician.com/2009/12/…
【解决方案2】:

Python random 模块使用基于时间的随机,其设计用于建模和模拟,而不是安全或密码学。

攻击者可以了解密钥的创建时间,这确实有助于他们潜在地暴力破解您的密钥。

在 python 3 中,您有 secrets 模块来解决此问题。

secrets documenation

【讨论】:

  • 这里的源代码说如果有os.urandom的话,会被播种...hg.python.org/cpython/file/2.7/Lib/random.py ..是不是说os.urandom有的话就安全了?
  • 绝对不是。这意味着它取决于您的操作系统类型。
  • @surbhi 不,它仍然不安全,因为 PRNG 的状态可以通过足够的观察次数来确定,这将允许您在不知道种子的情况下预测未来的随机数。如果 os.urandom 可用且安全,则 random.randint 如果您在每次调用之前播种它是安全的(但在这种情况下您最好直接调用 os.urandom)。
猜你喜欢
  • 1970-01-01
  • 2012-10-07
  • 2011-11-10
  • 2013-09-20
  • 2016-08-15
  • 2012-12-19
  • 1970-01-01
  • 2020-06-13
相关资源
最近更新 更多