生成加密安全的伪随机数

RandomThreadLocalRandom 足以满足日常使用,但它们有一个很大的问题:它们基于线性同余生成器 ,这种算法的输出可以很容易地预测。因此,这两个类是适于密码用途(如密钥生成)。

在需要具有非常难以预测的输出的 PRNG 的情况下,可以使用 java.security.SecureRandom。预测由此类的实例创建的随机数很难将类标记为加密安全

import java.security.SecureRandom;
import java.util.Arrays;

public class Foo {
    public static void main(String[] args) {
        SecureRandom rng = new SecureRandom();
        byte[] randomBytes = new byte[64];
        rng.nextBytes(randomBytes); // Fills randomBytes with random bytes (duh)
        System.out.println(Arrays.toString(randomBytes));
    }
}

除了加密安全之外,SecureRandom 的巨大周期为 2 160 ,而 Randoms 期间为 2 48 。然而,它具有比 Random 和其他线性 PRNG(例如 Mersenne TwisterXorshift) 慢得多的一个缺点。

请注意,SecureRandom 实现依赖于平台和提供程序。默认的 SecureRandom(由 SUN 提供的 SUN 提供):

  • 在类 Unix 系统上,播种来自/dev/random 和/或/dev/urandom 的数据。
  • 在 Windows 上,在 CryptoAPI 中调用了 CryptGenRandom()