【问题标题】:I'd like to understand Java's SecureRandom object我想了解 Java 的 SecureRandom 对象
【发布时间】:2014-06-09 00:47:28
【问题描述】:

在学习初学者的加密课程时,我试图掌握 Java 的 SecureRandom 对象。我想我理解的是:

a) 无论你知道一个随机数序列有多长,都无法预测序列中的下一个随机数。

b) 不管你知道一个随机数序列有多长,除了暴力猜测之外,没有办法知道是哪个种子用来启动它们的。

c) 您可以请求各种大小的安全随机数。

d) 您可以为新创建的 SRNG 播种各种不同大小的值。您创建并使用相同值作为种子的每个新创建的 SRNG 都会产生相同的随机数序列。

我应该补充一点,我假设这段代码是在 Windows 上使用的:

Random sr = SecureRandom.getInstance("SHA1PRNG", "SUN");

我的基本理解正确吗?提前致谢。

我还有一些问题想问那些在加密方面相当专业的人。它们与播种 SRNG 相关,而不是让它在首次使用时自行播种。

e) 如果您使用长整数而不是 8 字节数组作为 SRNG 的种子,那么生成的随机数有什么区别?

f) 如果我使用 256 字节作为 SRNG 的种子,是否还有其他种子可以产生相同的随机数序列?

g) 是否有某种最佳种子大小?在我看来,这可能是一个毫无意义的问题。

h) 如果我通过使用 256 个字节播种 SRNG 来加密明文,然后让它生成随机字节以与明文中的字节进行异或运算,那么窃听者解密得到的密文有多容易?可能需要多长时间?我是否认为窃听者必须知道、猜测或计算 256 字节的种子?

我已经查看了以前有关 SecureRandom 的问题,但似乎没有一个能够回答我的特殊问题。 如果这些问题中的任何一个看起来过于愚蠢,我想重申一下,我是这个领域的初学者。非常感谢任何输入,因为我想了解 Java SecureRandom 对象如何用于密码学。

【问题讨论】:

  • 一个问题就有很多问题。不过,我认为您的理解在很大程度上是正确的。
  • 对问题数量感到抱歉。这是我在这里的第一篇文章。
  • 这些都是很好的问题,但每个问题的回答都需要几段。我建议单独发布它们。顺便说一句,如果您想要特定于 SHA1PRNG 算法的答案,或者更广泛地了解 Pseudo-RNG,请澄清。

标签: java random cryptography


【解决方案1】:

d) 这对于 PRNG 来说是正确的。对于 CSRNG,情况并非总是如此。阅读 SecureRandom.setSeed() 的 Javadoc:“给定的种子是对现有种子的补充,而不是替换。因此,保证重复调用永远不会减少随机性。”

任何合理的 CSRNG 都将具有您无法明确控制的“不可见”熵源,通常是从操作系统级别获取的各种内部参数。因此,播种数量比您明确传递给 RNG 的任何数量都多。

【讨论】:

  • 谢谢。我在 Javadoc 中读过这个,但运行了一系列连续调用来播种新的 SecureRandom,然后要求它提供一系列长值。每次出来的数字都是一样的。我不记得我重复了多少次测试,但如果它甚至会改变一次,那么这样的种子就不能每次都用于加密和解密相同的消息。
  • 如果您正在加密和解密,那么您需要一个Stream Cipher,如RC4 或eSTREAM 密码之一。流密码基本上是一种 PRNG,其输出完全取决于种子/密钥。
  • 谢谢,但我没有加密或解密。我在学习。并试图找出使用种子 Java SecureRandom 对象的弱点。
【解决方案2】:

好的,按顺序:

a) 正确

b) 正确

c) 正确,您甚至可以使用 nextInt(n) 请求 [0, n) 范围内的数字

d) 与正确一样好:SHA1PRNG 的实现未由任何算法公开定义,并且有迹象表明实现及时更改,因此这仅适用于 Sun 提供商,然后只针对特定的运行时配置

e) 因为 API 清楚地表明使用了 long 中的所有字节(“使用给定的 long 种子中包含的八个字节”),所以添加到状态的熵量应该没有任何差异

请注意,快速检查显示setSeed(long) 的行为与setSeed(byte[]) 完全不同,主要区别在于long 值的种子总是与从系统检索到的随机性混合在一起,即使它是第一个在构造 SecureRandom 实例后调用。

f) 是 - 无限数量的种子生成相同的流;由于使用了哈希函数,因此将无法找到一个

g) 如果你加入额外的熵,那么熵越多越好,但没有最小值;如果你使用它作为唯一的种子,那么你不应该从小于 20 字节的种子开始,也就是说:如果你想让种子保持与 PRNG 的内部状态相同的安全约束

我还要补充一点,如果您使用的熵少于 64 字节,那么您肯定处于危险区域。请注意,1 位熵并不总是意味着一个字节中的 1 位。大小为 8 的字节数组可能有 64 位熵或更少

h) 这基本上是一个基于散列的流密码;它是安全的,因此攻击者几乎没有机会(假设您不重复使用种子),但它非常不可靠(参见答案 d)和慢速流密码,所以请永远不要这样做- 使用 Cipher"AES/CTR/NoPadding""AES/GCM/NoPadding" 代替

【讨论】:

  • 太棒了!这解决了我缺乏全面理解的每一个点,然后是一些。并且还指出了我更多的研究课题。谢谢:-)
【解决方案3】:

e) 我不认为这有什么不同。假设 long 和 8 字节数组包含相同的数据。

f) 原则上,是的。如果您的种子大于 RNG 的内部状态,则可能存在一些其他种子会导致相同的内部状态。如果种子小于状态,则不应该存在。我不知道 SecureRandom 的内部状态是什么样的。

g) 重要的不是种子的大小;这是其中的熵量。您的种子中的熵至少需要与您期望从 RNG 中获得的安全性一样多;我不太确定这里有哪些最佳做法。

h) 我不确定破解您建议的基于 RNG 的流密码有多容易。但我建议不要在实践中使用它,因为它不是经过专家审查并具有合理安全证明的标准密码结构。记住加密规则:

  1. 永远不要设计自己的加密货币。
  2. 永远不要实现自己的加密。
  3. 任何人都可以设计自己无法破解的加密货币。

【讨论】:

  • 谢谢。我只是想理解。并且想知道使用我选择的任何特定值作为种子的 SRNG 会有多弱,而不是说 /dev/urandom 或等价物。
  • 鉴于人类并不擅长生成随机数,我强烈建议不要自己编造种子。另外,如果你使用硬编码的种子,随机流每次都是一样的。
  • 是的,我意识到这一点,谢谢。我不想加密任何东西,我只是想了解为什么这种加密方式很弱,以及破解它需要多长时间。
猜你喜欢
  • 2019-06-29
  • 2020-02-08
  • 1970-01-01
  • 2019-11-20
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多