6

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

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

4

2 回答 2

3

警告

在我看来,直接依赖这个算法是不好的。请在 SO 上查看此答案,其中我说明了为什么依赖特定SecureRandom算法是不好的。

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

简短的介绍

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

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

算法的属性

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

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

不幸的是,没有对可用算法的明确描述,并且不同的提供者可能会以不同的方式实现它,通常试图模仿 Java 的实现(有时很糟糕甚至不安全)。

确定性操作

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

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

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

笔记

请注意,SHA1PRNG 的实现可能因 JCA 提供者/不同的运行时而异。与 SUN SHA1PRNG 相比,Android 上的代码尤其不同且稳定性较差。请仅用SecureRandom于其预期目的:生成安全随机值

于 2014-04-01T11:21:58.620 回答
1

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

于 2012-10-04T11:41:17.997 回答