Java 9 引入了一个名为 DRBG 的新 SecureRandom。我想用它来确定性地生成随机数。问题是它在内部使用了一个随机数,它总是在变化,所以我没有为相同的种子得到相同的数字。它确实有一个内部选项来设置该随机数,但我找不到任何可以实现这一点的公共方法。我怎样才能改变那个随机数?
1 回答
该SecureRandom
课程仍然指出:
此外,
SecureRandom
必须产生非确定性的输出。
尽管列出的 DRBG 方案是确定性的,但它们仍将由运行时环境播种,运行时环境通常从操作系统检索熵。
在这方面,“DRBG”的含义可能有些混乱。尽管底层算法本质上是确定性的,但这意味着它依赖于种子中的熵来生成比特流。这些随机位在计算上与随机位无法区分,即使它们只包含有限数量的熵。如果对手可以猜到种子,那么整个流就变得已知了。但是如果种子包含足够的熵,那么这在实践中是不可能的。
“DRBG”只是指一种预先配置且定义明确的 NIST 标准化算法(可以在这个问题的答案中看到)。因此,它与“SHA1PRNG”不同;“SHA1PRNG”是 Sun 的一种专有算法,它完全没有指定,而其他实现(例如 Android 中的实现)既不同又不安全。早期版本的 Java 确实允许您在从中检索任何输出之前从播种的“SHA1DRBG”确定性地生成安全随机值。
你可以自己创建一个SecureRandomSpi
确定性的,但是你会违反SecureRandomSpi
. 如果你这样做了,你当然必须实现一个提供者。
实施SecureRandomSpi
将是正确的方法,但请注意,您实际上可以从继承,SecureRandom
因此有一个捷径,如果有点破解的话。
要获得快速、确定性的“随机”实现,您可能希望在下面使用流密码。这比 DRBG 更有效,并且它没有重新播种的功能,你绝对可以不用。可能您还需要实现一个 KDF 来生成 DRBG 所需的密钥。
如果您采用这种方式,请明确指定您的协议,否则开发人员将不得不对您的代码进行逆向工程以获取所使用的算法。