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