2009-08-06 151 views
4

我目前正在嘗試修改現有的GWT-Ext應用程序,即在MySql數據庫中使用純文本密碼。在GWT/GWT-Ext中密碼字符串的md5散列?

我的計劃是使用md5哈希函數,因爲現有的密碼可以很容易地通過MySql函數進行修改,而且我期待爲GWT-Ext端找到一個簡單的解決方案。但正如我發現的那樣,GWT不支持java.security,並且似乎沒有任何其他實現可用於將密碼字符串更改爲客戶端上的md5散列。

只有「解決方案」我發現至今,是重新實現通過JSNI一個MD5方法如下所述: http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/ad09475a9944c9f8

沒有爲EXT-JS的現有用戶擴展,但我無法找到任何GWT-Ext: http://extjs.com/forum/showthread.php?p=133516

有沒有人知道更優雅/簡單的方法來解決這個問題?也許我應該使用別的東西而不是md5來確保密碼被加密?

乾杯 弗蘭克

回答

9

就個人而言,我會說你這樣做是錯誤的。我不會在客戶端散列密碼(這是GWT的)。如果你把你的密碼拼湊在一起,你無疑會想要用它來欺騙它,否則你將很容易受到rainbow攻擊。如果你在客戶端散列+鹽,你的用戶可以訪問你的salt。

如果我是你,我會在服務器端散列+ salt密碼。這將允許您使用標準的Java代碼來執行MD5哈希。

我的2美分。

-jP

+0

如果他在客戶端執行類似cram-md5的事情,客戶端計算hmac(md5哈希加上一個隨機數salt)並將其發送到服務器,那麼這不是一個錯誤的方案。缺點是服務器需要明文密碼才能檢查hmac。 – 2009-08-06 18:59:02

+0

關於彩虹攻擊的好處,以前不知道。我也通過在服務器端進行加密來解決這個問題,但是我的想法是,在將密碼發送到服務器之前,我想加密密碼,因爲我們目前只使用http而沒有https。 – FrankS 2009-08-06 21:27:57

+0

GWT是客戶端和服務器端。除此之外,這個職位是很好的建議。不要在客戶端散列它。看看http://www.owasp.org/index.php/Hashing_Java。 – 2009-09-01 12:33:05

6

,可能適合你需要的是一些所謂的零知識權威性另一個想法。 (即服務器永遠不需要知道用戶的明文密碼)

基本上,在設置初始密碼時,客戶端將用戶密碼哈希N次(其中N是1000的較大數字),然後發送服務器存儲散列和N.

稍後,當用戶想要認證時,服務器告訴客戶端N-1,並且客戶端清除了用戶鍵入的密碼N -1次併發送到服務器。服務器對收到的散列做了1次散列,並且(希望)得到存儲的散列。服務器然後存儲N-1哈希和N-1號碼。

每次用戶認證,服務器遞減存儲的N並保存以前的散列值。

當N下降到0時,用戶必須選擇並設置一個新密碼。

服務器必須確保它從不要求相同的迭代,否則它很容易重播。你不能真正從客戶端執行這個條件,因爲客戶端(尤其是瀏覽器)不能可靠地跟蹤最後一個N.

+0

非常有趣的想法,並沒有想過之前。目前的解決方案並不適合,但我會牢記以備將來參考,謝謝:-) – FrankS 2009-08-07 07:59:20

+1

有趣的想法讓我花了一些時間思考它,但它很容易受到中間人攻擊。 在認證請求上,服務器發送一些數字M.攻擊者發送(M-1)到客戶端,並接收到散列(M-1)。攻擊者嘗試再次進行身份驗證,從服務器接收挑戰(M-1),並使用散列(M-1)進行響應。攻擊者現在被認證。 – rix0rrr 2010-01-06 11:14:44

+0

是的,這聽起來像一個問題。我首先想到的是要求服務器在向客戶端挑戰期間發佈它時不重用M。然而,更大的問題仍然是Mallory可以告訴客戶端M-100,從客戶端收集哈希(M-100),然後用截獲的哈希登錄多達100次。我將不得不去看看我第一次遇到這個項目是否找到了相同的問題並處理了它,或者放棄了零知識驗證。 – 2010-01-06 16:57:40

2

您可以使用gwt-crypto使用生成的客戶端SHA-1哈希:

String getSHA1for(String text) { 
    SHA1Digest sd = new SHA1Digest(); 
    byte[] bs = text.getBytes(); 
    sd.update(bs, 0, bs.length); 
    byte[] result = new byte[20]; 
    sd.doFinal(result, 0); 
    return byteArrayToHexString(result); 
} 

String byteArrayToHexString(final byte[] b) { 
    final StringBuffer sb = new StringBuffer(b.length * 2); 
    for (int i = 0, len = b.length; i < len; i++) { 
    int v = b[i] & 0xff; 
    if (v < 16) sb.append('0'); 
    sb.append(Integer.toHexString(v)); 
    } 
    return sb.toString(); 
}