在SecureRandom类中使用“SHA1PRNG”

时间:2012-10-04 11:38:32

标签: java cryptography

我有一个基本问题。为什么'SHA1PRNG'用于SecureRandom类。如果有人解释它会很有帮助。提前谢谢。

EX: SecureRandom.getInstance( “SHA1PRNG”);

2 个答案:

答案 0 :(得分:2)

警告

在我看来,直接依赖这个算法是不好的。请参阅this answer on SO我在哪里显示为什么依赖于特定的SecureRandom算法是错误的。

请注意,虽然大多数运行时都有一个"SHA1PRNG"实现的提供程序,但Java规范需要算法的实现,因此它可能会失败{{1}如果你只是假设它总是在那里。

简短说明

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

实施的优点是PRNG独立于OS运行,它不依赖于例如"SHA1PRNG"/dev/random。这可以带来性能优势,也可以帮助防止OS熵池的耗尽(系统随机性所依赖的数据)。

算法的属性

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

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

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

确定性操作

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

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

这在测试期间非常有用,但请不要依赖生产代码中的此属性。即使SUN SHA1PRNG实现已经发生了变化,因此您不能依赖输出在不同版本上保持不变。

备注

请注意,SHA1PRNG的实现可能因JCA提供程序/不同的运行时而不同。 Android上的代码特别与SUN SHA1PRNG不同且不太稳定。 请仅将nextXxx()用于其预期用途:生成安全随机值

答案 1 :(得分:1)

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