生成加密安全的伪随机数
Random
和 ThreadLocalRandom
足以满足日常使用,但它们有一个很大的问题:它们基于线性同余生成器 ,这种算法的输出可以很容易地预测。因此,这两个类是不适于密码用途(如密钥生成)。
在需要具有非常难以预测的输出的 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 ,而 Random
s 期间为 2 48 。然而,它具有比 Random
和其他线性 PRNG(例如 Mersenne Twister 和 Xorshift) 慢得多的一个缺点。
请注意,SecureRandom 实现依赖于平台和提供程序。默认的 SecureRandom
(由 SUN
提供的 SUN
提供):
- 在类 Unix 系统上,播种来自
/dev/random
和/或/dev/urandom
的数据。 - 在 Windows 上,在 CryptoAPI 中调用了
CryptGenRandom()
。