生成加密安全的偽隨機數
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()
。