我有一个基本问题。为什么'SHA1PRNG'用于SecureRandom类。如果有人解释它会很有帮助。提前谢谢。
EX: SecureRandom.getInstance( “SHA1PRNG”);
答案 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。只是确保生成的随机数尽可能接近“真正随机”。容易猜到的随机数会破坏加密。