SecureRandom类中“SHA1PRNG”的使用

7

我有一个基本问题。为什么在SecureRandom类中使用'SHA1PRNG'。如果有人能解释一下,那就太好了。提前感谢。

例如: SecureRandom.getInstance("SHA1PRNG");


有关SHA1PRNG实现的有趣讨论,请参见此处:https://dev59.com/_HfZa4cB1Zd3GeqPPD3f。 - Maarten Bodewes
2个回答

4

警告

在我看来,直接依赖此算法是不好的。请参见SO上的这个答案,在那里我展示了为什么依赖特定的SecureRandom算法是不好的。

请注意,尽管大多数运行时都有一个带有"SHA1PRNG"实现的提供程序,但Java规范不要求实现该算法,因此如果您简单地假设它总是存在,则可能会出现NoSuchAlgorithmException错误。

简短描述

"SHA1PRNG"是伪随机数生成器的名称(名称中的PRNG)。这意味着它使用SHA1哈希函数生成一系列随机数。SHA1PRNG是Sun在当时引入的专有机制。

实现的优点是PRNG独立于操作系统运行,不依赖于例如/dev/random/dev/urandom。这可以带来性能优势,也可以帮助防止操作系统熵池(系统随机性所依赖的数据)的枯竭。

算法属性

SHA1哈希函数用于创建RNG的输出并在使用PRNG之前对种子信息进行哈希处理。SHA1PRNG输出与内部状态分离(因此攻击者不能仅使用RNG的输出来重新创建内部状态)。

内部状态相对较大(在Java 1.7中,SHA1PRNG当前仅限于160位哈希大小)。这意味着几乎不可能创建循环。如果遇到相同的内部状态,则会创建循环-以下状态也将相同(除非使用setSeed()添加额外熵)。

很遗憾,没有可用的算法明确描述,并且不同的提供程序可能以不同的方式实现它,通常试图模仿Java的实现(有时是不好的甚至是不安全的)。

确定性操作

PRNG是确定性的。这意味着它们将始终从相同的输入材料(“种子”)生成相同的随机数流。然而,SUN SHA1PRNG将自行从操作系统检索到的熵种子自身种子化,当第一次访问随机池时。在这种情况下,随机值将无法与真正的随机数生成器区分开来。

SUN SHA1PRNG的一个特殊属性是,只有在使用nextXxx()方法之前调用setSeed()给定种子时,它才会使用该种子。在这种情况下,流仅取决于给定的种子和实现的算法;在这种情况下,PRNG是完全确定的;如果调用相同的方法,则它将始终返回相同的“随机”值。
这在测试期间非常有用,但请不要在生产代码中依赖此属性。即使SUN SHA1PRNG实现也经历了变化,因此您不能指望输出在不同版本上保持不变。
注:SHA1PRNG的实现可能因JCA提供程序/不同运行时而异。Android上的代码特别不同且不太稳定。请只使用SecureRandom来生成安全随机值

你好,能否帮我看一下这个问题:https://stackoverflow.com/questions/64786678/javascript-equivalent-to-java-sha1prng?谢谢! - Qiulang

1

请参阅有关该主题的IBM Docs。这只是确保生成的随机数尽可能接近“真正随机”。易于猜测的随机数会破坏加密。


1
同样有趣的是什么构成了“好”的随机数。阅读相关资料,但你的头会爆炸。 - Tony Ennis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接