2013-04-08 183 views
0

我想寫一個密碼加密類,我可以用它來加密和存儲用戶密碼。我想確保我正確地做到了這一點。此代碼工作正常,似乎生成一個加密的密碼,但我想在這裏發佈,以獲得一些反饋。對我而言,這是相當複雜的,並且我知道加密中的任何事情,在沒有意識到你正在製造它們的情況下很容易犯錯。密碼加密

這裏是我的代碼:

public CipherHandler { 

     public String encryptPassword(char[] plaintext, String encoding) throws Exception { 

      MessageDigest msgDigest = null; 
      String hashValue = null; 

      /* Convert char array plaintext to byte array */ 
      byte[] b = new byte[plaintext.length << 1]; 
      for (int i = 0; i < plaintext.length; i++) { 
       b[i] = (byte) plaintext[i]; //will this work regardless of encoding? 
      } 

      try { 
       msgDigest = MessageDigest.getInstance("SHA-256"); 
       msgDigest.update(b); 
       byte rawByte[] = msgDigest.digest(); 
       hashValue = (new BASE64Encoder()).encode(rawByte); 
      } catch (NoSuchAlgorithmException e) { 
       System.out.println("No Such Algorithm Exists"); 
      } 

      System.out.println(hashValue); 
      return hashValue; 
     }    
    } 

此功能一般會從Swing事件處理程序在用戶輸入密碼進入JPassword場,這就是爲什麼我開始用炭稱爲[] 。爲了測試,我使用此代碼來調用該函數:

CipherHandler cp = new CipherHandler(); 
String initPW; 
try { 
    initPW = cp.encryptPassword("welcome".toCharArray(), "UTF-8"); 
} 

由於這是我第一次嘗試,我想,我忽略了一些東西。我對感興趣建議或意見。我有幾個具體的問題,雖然:

  1. 當我的char []轉換成一個byte [],我不相信,我正確地做這個。我如何知道使用哪種編碼?在這裏,我放置了「UTF-8」,主要是作爲佔位符,但我擔心在某些情況下這可能會失敗。

  2. 我已經讀過,我應該在密碼被消化後使用鹽和迭代,但我無法弄清楚如何做到這一點。有人可以請教我這個嗎?

  3. 我正在使用SHA-256。這是建議的算法嗎?我也讀過關於MD5的內容。是否有一種算法適用於密碼加密?

感謝您的任何幫助。我很感激!

+3

參見[如何安全地散列密碼?](http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords)。 SHA-256不適合密碼散列,並且需要鹽。 – CodesInChaos 2013-04-08 18:35:19

回答

1

通常,密碼是通過散列存儲的,而不是通過加密存儲的。

MessageDigest md = MessageDigest.getInstance("SHA-256"); 
byte[] hash = md.digest(password.getBytes("UTF-8")); 

再對比一下新生成散列您已經存儲在數據庫中或其它地方的哈希值。

將密碼加密也是一個好主意 - 這是一個明文值,您可以在對密碼進行哈希處理之前將其附加到密碼中。這使得有人執行離線暴力攻擊更加困難。

+2

醃製是不夠的,你還需要一個昂貴的散列。優選的scrypt,bcrypt或者PBKDF2,但是迭代的SHA-2也可以。單迭代SHA-2不好。 – CodesInChaos 2013-04-08 18:36:58

+0

謝謝。你發佈的代碼與我的代碼有什麼不同?你正在使用一個字符串密碼(據推測),我已經閱讀是一個壞主意,因爲它們是不可改變的,可以在內存中生活一段時間。我正在使用一個char [],它需要多個步驟才能轉換爲byte [],但是當我比較這兩個代碼片段時,它們都使用MessageDigest變量並摘要化該變量。爲了返回目的,我將加密(哈希)密碼變回字符串,但它們看起來基本相同。我錯過了什麼嗎?謝謝! – Alex 2013-04-08 18:40:56

+0

我同意你關於醃製。有人可以建議我怎麼做?我被困在這一點上。 – Alex 2013-04-08 18:41:47

0

MD5已經死了,而UTF-8應該可能是您最小的擔憂。閱讀this
當然,根據您的密碼加密目的(取決於您獲得的目標受衆類型),如果您在安全堆棧交換中搜索了足夠長的時間,則可以爲您的挑戰找到完整答案。

只是我的$ 0.02