2011-01-13 63 views
1

我一直在與Java的SecureRandom類一起工作,以生成鹽用於以後的加密和密碼散列(我爲每個任務生成單獨的鹽)。我一直在使用的代碼如下:Java和密碼學強隨機數

//Init random number generator 
secureRandom = SecureRandom.getInstance("SHA1PRNG"); 
secureRandom.setSeed(System.nanoTime()); 

//Create salts 
secureRandom.nextBytes(bytAuthSalt); 
secureRandom.nextBytes(bytEncryptionSalt); 

現在,一切都很好,直到我開始真正驗證我得到的值。對於應用程序的幾個連續執行我的鹽是:

[[email protected] 
[[email protected] 
[[email protected] 
[[email protected] 
[[email protected] 
[[email protected] 

我對這些數字似乎都大致順序感到不安。在網絡上進行了一些搜索之後,我再次重複了這些運行,而沒有將它自己播種到相同的結果。

我唯一的猜測是什麼可能是由於我正在爲Android平臺開發的事實。我知道他們有自己的密碼提供者,但我沒有任何例外。有任何想法嗎?

在此先感謝。

回答

9

看起來你打印出的是字節數組的引用而不是其內容。這就是爲什麼它們是連續的,參考基本上是給你在JVM內存中的位置。在打印之前將字節數組轉換爲字符串。

String saltContents = Arrays.toString(bytAuthSalt); 

陣列轉換到使用Arrays將顯示字節的原始值的字符串。

+3

如果我沒有弄錯,那將使用默認字符集來解釋字節,而不是打印出原始字節。 OP不需要原始字節而不是ASCII等效字符? – 2011-01-13 16:49:08

+1

@ RD01 - 但仍然會給OP一個很好的隨機性視圖。 – Rogach 2011-01-13 16:50:57

4

似乎您正在打印一個數組,而不是實際值。 「[B @」告訴你它是一個字節數組,而它後面的所有對象都是id。
嘗試是這樣的:

System.out.println("bytAuthSalt"); 
    for (byte b : bytAuthSalt) { 
    System.out.print(b); 
    } 
    System.out.println(); 

或者這樣:

Arrays.toString(bytAuthSalt); 

這將打印數組的所有值。

1

我也建議不要使用播種System.nanoTime(),因爲它不能保證在所有平臺上正常工作。在某些情況下,它只返回'零',我認爲這是不適合播種RNG的數字。

2

SHA1PRNG只與其種子一樣安全。出於這個原因,使用System.nanoTime()作爲種子是一個可怕的想法。可以充分縮小播種時間範圍的攻擊者可以嘗試所有可能的值,直到他找到匹配序列。攻擊者得益於這樣的事實:System.nanoTime()的分辨率通常比1納秒大得多。

只要做new SecureRandom()就可以讓JRE選擇最好的實現。在大多數平臺上,這將使用OS本地熵源來播種RNG,例如/dev/random