2013-11-09 64 views
1

我正在開發基於Web和客戶端應用程序的系統;客戶端在PHP和Http請求的幫助下在服務器中完成所有數據庫查詢。 Web系統是用PHP/Mysql開發的,安裝在PC上的客戶端應用程序是用C#開發的。加密:爲密碼做一個更強的散列

好!在一個階段,客戶端必須通過登錄來識別用戶,這看起來像一個簡單的任務,但服務器IP可以通過應用程序配置部分進行更改。考慮到這一點,任何邪惡的人都可以通過輸入惡意服務器的IP地址進行網絡釣魚,然後竊取密碼,事情是,我不會以文本/純文本的形式從客戶端發送密碼。

現在我正在使用md5進行密碼散列(沒有鹽,只是純散列),我只用它來存儲數據庫的密碼。

閱讀了一下後,我意識到人們不推薦使用md5了,而是使用sha256或更高版本,我正在考慮遷移到更好的散列算法並創建自己的鹽。

據我所知鹽只是一個隨機的一段文字添加到哈希,但我不認爲這是最好的選擇,所以我在想的東西:

由於哈希值是基於對於十六進制值,小寫字母和固定長度(32,64等等,取決於算法),我可以使用加載在列表(數組)中的固定值的總和來對每個散列字符的ASCII代碼進行處理,例如:

我:每個字母ABCD

ASCII碼:

一個 - > 97

乙 - > 98

Ç - > 99

d - > 100

然後我總結列表的固定值(具有32的長度/ 64個根據整數)這樣

一個 - > 97 + 5 = 102 =>˚F

乙 - > 98 + 2 = 100 => d

Ç - > 99 + 7 = 106 =>Ĵ

d - > 100 + 3 = 103 =>克

所以結果將是:FDJE它取代ABCD的散列。

我不知道它有多安全,黑客決定我使用的技術有多困難,結果是結果與散列長度相同,並且很難確定鹽,所以如果出於歷史上的任何原因,黑客使用彩虹桌並捕獲可能的結果,那將是錯誤的。你怎麼看待這件事?

謝謝...

+0

請不要設計新的安全基元,至少不要自己先欺騙自己是專家。 –

+0

讓我感到緊張的是這樣的:「[...]客戶端在PHP和Http請求的幫助下在服務器上完成所有數據庫查詢。」您能詳細說明一下嗎?您的客戶意味着什麼使數據庫查詢?它是否生成它們並將它們發送到數據庫以供執行? – Gumbo

+1

[不要推出自己的加密](http://security.stackexchange.com/q/18197/20774)。使用scrypt,bcrypt或pbkdf2。 – 1615903

回答

1

一個簡單的置換密碼是不太可能放慢意志堅定的黑客很長時間。

你最大的問題是有人與你的客戶端可以建立一個你正在爲特定值生成的哈希表。在密碼字段中輸入a,捕獲哈希。在密碼字段中輸入b,捕獲哈希。使用這種數據,即使是醃製的,也可以很容易地對您的方法進行逆向工程。

我認爲你最好的選擇是使用某種公鑰/私鑰對,這樣客戶端只會信任你的服務器,而不會與其他任何東西進行通信。

我也認爲你誤解了salting - 你不會將字符添加到散列,你將它們添加到你正在哈希的值。認爲hash(password + salt)而不僅僅是​​。

+0

+1來澄清鹽的工作原理 – Neo

1

服務器IP可以通過應用程序配置部分進行更改。考慮到這一點,任何邪惡的人都可以通過輸入一個邪惡的服務器IP地址進行網絡釣魚,然後竊取密碼

這並不是威脅模型。如果攻擊者可以在客戶端上執行代碼來重新配置用戶的應用程序,那麼他們可以在任何靠近服務器的地方攔截所有擊鍵。

事情是,我不會以文本/純文本的形式從客戶端發送密碼。

保護連接的常規方法是使用SSL,這可以很好地將密碼從客戶端發送到服務器。必要的服務器證書還會負責向客戶端驗證服務器的身份(儘管這仍然無法解決受損客戶端端點的問題)。如果您不喜歡支付商業CA,您可以使用自己的CA基礎設施。

如果您建議將哈希從客戶端傳遞到服務器而不是密碼,那麼您將獲得一個密碼等同哈希,如果泄露的話密碼會遭受許多與密碼相同的風險。這也意味着客戶端和服務器必須同意散列算法,所以你不能包含salt,這意味着你仍然在服務器數據庫中存儲了易碎易碎的哈希。

對十六進制編碼散列中的數字運行固定的替換密碼將提供非常少量的默認值,這隻會阻止最懶的攻擊者。我不認爲值得費心的是,有一個很好理解的標準安全系統提供更好的保證:HTTPS用於連接和密碼存儲的bcrypt(password_hash)。

(如果你真的需要連接到你不信任的服務器,也有像SRP PAKE算法,但它是一堆的工作,留下了的密碼被如何設置和管理的問題第一個地方,沒有連接層加密,協議的其餘部分就不受保護。)

1

您可能會誤解鹽和鹽的密碼意味着一般情況。鹽漬密碼用於防禦彩虹表(這是預先計算的值的大表)。現在,生成一次彩虹表是黑客必須做的最昂貴的操作,而彩虹表的整個概念是加速暴力破解。

散列的目的是消除一個散列表/彩虹表可以爲一個密碼生成然後用於另一個密碼的可能性。鑑於你有一個固定鹽生成算法,任何攻擊者可以確定算法並使用它對你。

鹽應該生成隨機並存儲在密碼本身的某處的純文本。鹽也應該是唯一的每個密碼(如果你使用適當的隨機鹽產生器,這應該是非常有效的)。通過這樣做,您可以確保一個密碼的彩虹表對另一個密碼不可用。

現在已經完成並粉碎了,我們繼續討論更大的問題:使用簡單的散列算法進行密碼存儲。


沒有進入太多細節,但現實是如下:

GPU和其它集成電路(如ASIC/FGPA)已經成爲快。像Message Digest 5,Secure Hash Algorithm 1/2這樣的簡單哈希算法可以以令人滿意的速度進行計算,並且密碼可以像微波爐中的爆米花一樣被破解。

爲了解決這個問題,專用密碼存儲/散列算法等PBKDF#2bcryptscrypt已經開發了有目的地的資源密集和順序(如在不能並行,在一定程度上),以保持所述GPU和在海灣的ASIC。

你的帖子提到你正在使用PHP,所以讓我給你介紹一下你可能會選擇實現的簡單可笑的解決方案。從PHP 5.5開始,有兩個關鍵的新功能password_hash()password_verify(),它們爲您完成所有艱難而複雜的工作。

考慮以下代碼:

$pass = 'foobar'; 

//Generates a password hash 
$hash = password_hash($pass, PASSWORD_DEFAULT); 

就這樣,PHP已經散列密碼,你(在寫作的時候bcrypt)使用推薦的密碼哈希和安全鹽醃的密碼,你和格式化爲輸出到單個字符串中進行存儲。

要驗證是否給定的密碼是正確的:

$pass_to_verify = ... 

//$hash variable retrieved from the previous password_hash() function. 
if(password_verify($pass_to_verify, $hash)){ 
    //Password is correct 
}else{ 
    //Password is not correct 
} 

使用這兩個功能,你可以確保(只要在PHP的人不要亂了),你的密碼是固定以防止暴力破解。重複迭代許多人一直在說的語句:不執行你自己的加密,除非你完全知道密碼和哈希算法的全部概念(在這種情況下,你可能甚至不會在SO上發佈)。