使用Random來生成隨機數的危險性

咱們先來看一個實例java

public class SecureTest {
    public static void main(String[] args) {
        Random random1 = new Random(23468);
        for (int i = 0;i < 10;i++) {
            System.out.println(random1.nextInt(1000));
        }
        System.out.println("");
        Random random2 = new Random(23468);
        for (int i = 0;i < 10;i++) {
            System.out.println(random2.nextInt(1000));
        }
    }
}

運行結果linux

234
344
737
314
431
423
823
503
703
654app

234
344
737
314
431
423
823
503
703
654dom

通過比對,兩次隨機出來是否是很神奇,並且不管你隨機多少次,結果都同樣。這裏就有一個種子值的問題。ide

若是不寫種子值,其實Random會有一個默認的種子值,這個值就是 System.currentTimeMillis() ,因此咱們在代碼開發中,你通常不要使用System.currentTimeMillis()來做爲token之類的發送給用戶,不然將有可能會做爲攻擊憑證來獲取你的隨機數,那麼你的隨機數將無任何意義。spa

由於Random的種子可預測,咱們能夠使用SecureRandom來代替Random,SecureRandom是繼承於Random的一個類。雖然相同的種子產生的隨機數也相同,但SecureRandom的默認種子將再也不是System.currentTimeMillis(),而是操做系統裏面的一些隨機事件。操作系統

Instances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.
SecureRandom takes Random Data from your os (they can be interval between keystrokes etc - most os collect these data store them in files - /dev/random and /dev/urandom in case of linux/solaris) and uses that as the seed.
操做系統收集了一些隨機事件,好比鼠標點擊,鍵盤點擊等等,SecureRandom 使用這些隨機事件做爲種子
這些事件是存放在/dev/urandom裏面的。
因此基本上,除非黑客控制了你的操做系統,不然很難猜想出你的種子的。
public class SecureTest {
    public static void main(String[] args) {
        SecureRandom random1 = new SecureRandom();
        byte[] seeds = SecureRandom.getSeed(64);
        random1.setSeed(seeds);
        for (int i = 0;i < 10;i++) {
            System.out.println(random1.nextInt(1000));
        }
        System.out.println("");
        SecureRandom random2 = new SecureRandom();
        random2.setSeed(seeds);
        for (int i = 0;i < 10;i++) {
            System.out.println(random2.nextInt(1000));
        }

    }
}

運行結果blog

931
443
917
223
566
858
494
706
539
360繼承

931
443
917
223
566
858
494
706
539
360token

若是不手工設置種子值,就是取/dev/urandom裏面的值做爲種子值。

相關文章
相關標籤/搜索