從Java API文檔:
許多SecureRandom實現是一個僞隨機 數發生器(PRNG)的形式,這意味着它們將使用確定 算法,以產生僞隨機來自真隨機種子的序列。其他實現可以產生真隨機數,而其他實現可以使用兩種技術的組合。
所以,無論從/dev/random
nextBytes(bytes)
返回true隨機字節,或者是否返回從真正的隨機種子依賴產生的僞隨機數。第二種情況意味着使用初始隨機種子,通過對SecureRandom
的任何調用來生成確定性但看似隨機的(因此是僞隨機)數字序列。
Java 7允許指定可配置的PRNG源,但在Linux上默認的是NativePRNG
和Windows SHA1PRNG
。您也可以在Linux上指定SHA1PRNG
,但默認選項NativePRNG
更好。 SHA1PRNG
通過使用SHA1生成PRNG位和字節。在Linux上(可能還有其他的Unix,機制是「NativePRNG
」),算法從/dev/random
和/dev/urandom
中讀取,只要有足夠的熵可以通過這兩種方法獲得。爲了完整的對random
起見,從Linux手冊頁:
距離的/ dev/urandom的設備將不會阻止等待更多 熵讀取。因此,如果熵池中沒有足夠的熵,返回的值在理論上容易受到驅動程序使用的算法的密碼攻擊的影響。
因此,在Linux上至少,你SecureRandom
都會有一定量的真正的隨機輸出,直到/dev/random
塊由於熵的不足,但是如果你要求太多的隨機位,他們最終將開始由潛在的/dev/urandom
機器產生,其可以在PRNG中使用SHA1或其他加密散列算法。
這是最好創建一個SecureRandom
沒有指定自己的任何明確的種子,因爲它會(通過/dev/random
和/dev/urandom
默認爲NativePRNG
在Linux上)種子本身具有良好的種子。每隔幾分鐘呼叫nextBytes(bytes)
,即使是大量的字節,幾乎在任何情況下都不一定是問題。即使您使用的是NativePRNG
,它也會通過類似SHA-1的方式從/dev/urandom
獲取僞隨機字節,但其輸出仍然難以預測。
如果您要求提供千兆字節的隨機性,則可能需要使用SecureRandom
本身的某些輸出或提供自己的種子進行重新播種。請注意,它應該是安全的,爲setSeed()
提供任何類型的種子,因爲SecureRandom
通過將您提供的種子和以前的種子提供給SHA-1或另一種加密哈希算法等內部擴充當前種子。但是,最好創建初始SecureRandom
,而不要給自己的種子。
你可以告訴我有關java 7在Linux中的默認行爲。 – Trying
更新了我的答案。 –
什麼是使用SecureRandom的最佳方式?創建SecureRandom的實例並執行nextBytes?或者是其他東西。我每5分鐘致電nextBytes。它會有一些問題嗎? – Trying