我有一个基本问题。为什么在SecureRandom类中使用“SHA1PRNG”。如果有人对此进行解释,将很有帮助。提前致谢。

例如:
SecureRandom.getInstance(“SHA1PRNG”);

最佳答案

警告

我认为直接依赖此算法是不好的。请参阅this answer on SO,其中我展示了为什么依赖特定的SecureRandom算法不好。

请注意,尽管大多数运行时都将提供具有"SHA1PRNG"实现的提供程序,但是Java规范而不是要求算法的实现,因此,如果仅假设它始终存在,那么NoSuchAlgorithmException可能会失败。

简短的介绍
"SHA1PRNG"是伪随机数生成器的名称(名称中为PRNG)。这意味着它使用SHA1哈希函数来生成随机数流。 SHA1PRNG是当时Sun引入的专有机制。

实施的优点是PRNG独立于操作系统运行,它不依赖于/dev/random/dev/urandom。这可能会带来性能上的好处,也可能有助于防止OS熵池(系统随机性所依赖的数据)的耗尽。

算法的性质

SHA1散列函数用于创建RNG的输出,并对在PRNG中使用的种子信息进行散列。 SHA1PRNG输出与内部状态解耦(因此,攻击者无法仅使用RNG的输出来重新创建内部状态)。

内部状态相对较大(对于Java 1.7中的SHA1PRNG,当前限制为散列大小为160位)。这意味着几乎不可能创建周期。如果多次遇到相同的内部状态,则会创建一个循环-以下状态也将相同(除非使用 setSeed() 添加其他熵)。

不幸的是,没有可用的算法的清晰描述,并且不同的提供程序可能会以不同的方式实现该算法,通常试图模仿Java的实现(有时是严重的甚至是不安全的)。

确定性操作

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

SUN SHA1PRNG的一个特殊属性是,如果在使用setSeed()方法之一访问随机池以检索随机值之前调用了种子,则它将仅使用nextXxx()给定的种子。在这种情况下,流将仅取决于给定的种子和实现的算法;在这种情况下,PRNG是完全确定的;如果调用相同的方法,它将始终返回相同的“随机”值。

这在测试期间可能很有用,但请不要在生产代码中依赖此属性。甚至SUN SHA1PRNG的实现也发生了变化,因此您不能依靠输出在不同版本上保持不变。

笔记

请注意,在JCA提供程序/不同的运行时中,SHA1PRNG的实现可能有所不同。与SUN SHA1PRNG相比,Android上的代码尤其不同且不稳定。 请仅将SecureRandom用于其预期目的:生成安全的随机值

07-26 01:20
查看更多