2015-02-23 39 views
1

這是爲密碼生成鹽的正確方法嗎?Java SecureRandom as salt

 SecureRandom random = new SecureRandom(); 
     byte[] salt = random.generateSeed(64); 

     String decoded = new String(salt, "Cp1252"); 
     System.out.println(decoded); 

我想要生成新的密碼(SHA-512),所以我也需要一個鹽。
哈希密碼將=用戶密碼+鹽......這是正確的?
難道這些奇怪的字符會「破壞」DB(MySQL)嗎? (更新:無,因爲鹽應該是加密/編碼/散列並將結果shoudnt使用奇怪的字符)

幾個輸出:

ã2}wÑ»-ÄKÇæꮃzR4qÉÖÙÚ!ž0ÉW9;*Vß4x») 
àöˆ˜£¿{,J¼…HþTù#+Bv(Fp´G~Aò`^e_ElpíÜžS A!­ñÛz‹[email protected]`ý‡)‡ª€ 
5a£Æ.¥sgöfÈB:4-�y$Óx%Óâyý¾N¨…áq 

如果這些鹽也作爲encripted SHA-512? (更新:使用Base64庫Apache的公共編碼編碼,見下文)

更新

 SecureRandom random = new SecureRandom(); 
     byte[] saltArr = new byte[64]; 
     random.nextBytes(saltArr); 

     String salt = new String(saltArr, "Cp1252"); 
     System.out.println("SALT:"+salt); 


     byte[] encodedBytes = Base64.encodeBase64(saltArr); 
     System.out.println("Encoded SALT:" + new String(encodedBytes)); 

     byte[] decodedBytes = Base64.decodeBase64(encodedBytes); 
     System.out.println("Decoded SALT:" + new String(decodedBytes, "Cp1252")); 


     //SHA 
     String target = "Test"; 
     MessageDigest sh = MessageDigest.getInstance("SHA-512"); 
     sh.update(target.getBytes()); 
     StringBuffer sb = new StringBuffer(); 
     for (byte b : sh.digest()) sb.append(Integer.toHexString(0xff & b)); 
     System.out.println("Hashed PWD:"+sb); 

     //And then joining them together... 
+0

看看以下問題http://stackoverflow.com/questions/18142745/how-do-i-generate-a-salt-in-java-for-salted-hash – sasankad 2015-02-23 22:51:16

回答

1

首先,這將是足夠使用nextBytes(即實際調用PRNG),而不是generateSeed。後者使用種子生成算法,這是一種更復雜的操作,因爲它需要一個熵源(800-90A p19-23

鹽的主要功能是爲了防禦字典攻擊 與密碼散列值和列表針對預先計算的彩虹 表攻擊。 (Wikipedia

換句話說,you need a different salt for each password,但鹽不是祕密(你會與消化輸出一起存儲它),你 應該罰款從PRNG輸出。由於鹽(可能包含全部範圍內的字節0x00-0xFF)將作爲字符串持久化,所以它應該在Base64(或另一個字符集安全編碼,例如基本85, base64更平常)。

* SHA is not an encryption function

SecureRandom random = new SecureRandom(); 
byte[] salt = new byte[64]; 
random.nextBytes(salt); 

String password="god"; 
MessageDigest md = MessageDigest.getInstance("SHA-512"); 
md.update(password.getBytes(Charset.forName("UTF-8"))); 
md.update(salt); 

byte[] digest = md.digest(); 
+0

哦,是啊對不起,有時候我會把混淆與引語混淆......更新,請問你能檢查它是否正確嗎? – Alpha2k 2015-02-24 07:44:33

+0

是的。但請注意,getBytes()會使用平臺的默認字符集將字符串編碼爲一系列字節。如果您將應用程序遷移到另一個具有不同默認字符集的平臺,則相同的密碼和salt可能會散列爲不同的值;所以我用'getBytes(Charset)'。 還要注意'Integer.toHexString(0xff&b)'並不總是返回兩個字符。 – Javier 2015-02-24 10:13:19