很少有網站在將用戶密碼提交到服務器之前對其進行哈希處理。 Java甚至不支持SHA或其他算法。
但是我可以想到很多優點,例如防止跨站點洩漏或SSL所不提供的惡意管理員。
>為什麼這種做法在網站之間如此罕見?
很少有網站在將用戶密碼提交到服務器之前對其進行哈希處理。 Java甚至不支持SHA或其他算法。
但是我可以想到很多優點,例如防止跨站點洩漏或SSL所不提供的惡意管理員。
>為什麼這種做法在網站之間如此罕見?
JavaScript密碼哈希的發明人
早在1998年,我就建立了一個Wiki,這是我使用登錄系統建立的第一個網站。我無法負擔得起使用SSL託管的費用,但我擔心通過Internet傳輸的純文本密碼。我讀了有關CHAP(挑戰性哈希身份驗證協議)的書,並意識到我可以在JavaScript中實現它。我最終以獨立項目的形式發布了 JavaScript MD5,它已成為我開發的最受歡迎的開源軟件。 Wiki從未超越alpha。
與SSL相比,它有很多缺點:
我總是在前面就提到了這些限制。我曾經定期為他們發火。但是直到今天,我仍然堅持原來的原則:如果您出於某種原因未獲得SSL,那將比純文本密碼更好。在2000年代初期,許多大型提供商(最著名的是Yahoo!)都使用此軟件進行登錄。他們認為,即使僅用於登錄的SSL也會有太多開銷。我認為他們僅在2006年就登錄使用SSL,而在2011年Firesheep發佈時,大多數提供商都切換到了完全SSL。人們使用SSL代替。
客戶端哈希仍然有一些潛在的好處:
因此,第二個簡短的答案是:因為多因素身份驗證比客戶端密碼哈希更安全
。要了解此問題,首先您必須了解為什麼我們對密碼進行哈希處理。完全有可能以純文本格式將密碼存儲在服務器上,並將發送的密碼與收到的密碼進行比較。只要在傳輸過程中保護密碼,這就是一種安全的身份驗證方法(共享機密)。
密碼被散列的原因是問題不在於身份驗證,而在於存儲。如果服務器遭到破壞,攻擊者將立即訪問所有用戶帳戶,因為他們現在知道用於驗證用戶身份的機密。
散列對此構成障礙。由於服務器不知道進行身份驗證所需的實際輸入,因此即使對數據庫的妥協也無法授予攻擊者訪問用戶帳戶的權限。他們仍然需要找出輸入,以提供達到應用程序檢查的哈希值。當然,他們可以將所有值更改為他們知道的值,但這會很快引起懷疑,並且系統將關閉並受到保護。
因此,客戶端哈希處理的問題在於,它會有效地使哈希的結果是密碼而不是密碼。沒有什麼可以阻止攻擊者繞過官方客戶端,而只是將完成的哈希直接發送到服務器。它在身份驗證期間不會提供任何額外的(或損失)安全性,但是在哈希旨在防止的情況下,它沒有任何作用,因為存儲在數據庫中的哈希實際上是傳輸到服務器的共享機密。
也就是說,客戶端哈希確實為您提供了兩個值得注意的東西。雖然它根本無法幫助保護您的系統,但可能可以幫助保護您的用戶。如果您不安全地傳輸密碼或在不破壞客戶端代碼的情況下破壞了傳輸,您仍然可以防止用戶密碼(他們的密碼可能會在其他站點上重複使用)。
另一種方法是,您可以提供哈希的其他迭代,以使對DB的脫機攻擊更加困難,而不必使用服務器週期(同時還可以延長“客戶端提交的中間密碼”的長度),但是您仍然需要足夠的服務器週期來保護加長密碼以防惡意客戶端。再次,此提供的主要保護措施是防止發現原始密碼,但無助於保護您站點的身份驗證機制。從服務器的角度來看,應將客戶端哈希視為用戶的直接密碼。 與用戶直接提供密碼相比,它在服務器上提供的安全性 或多或少都沒有,並且應該受到同樣的保護。為了能夠提供額外的安全級別,我建議使用兩個哈希。哈希一次客戶端以構建一個新的唯一密碼,然後將該密碼哈希到服務器上以使值存儲在數據庫中。這樣一來,您可以兼得兩全。發送給客戶端的代碼,這樣就不會執行初始哈希。但這根本不是SSL的有效替代方法,並且沒有提供足夠的額外優勢來彌補成本和復雜性。
如果您有很多優點,則應在問題中列出它們,以便人們了解它們是否真正有用(如果這樣,您可能會出名;)
人們不會不建議使用客戶端哈希,因為它們具有更好的保護用戶私人信息的方法。讓我們考慮一下可能發生信息洩漏的地方,其中有三個:
然後讓我們看看為什麼客戶端哈希在這些地方有所幫助。
客戶端。
如果您自己的計算機上存在惡意軟件,例如,如果您的瀏覽器受到感染或您的計算機植入了密鑰記錄軟件,則客戶端哈希不會阻止黑客獲取您的密碼。原因很明顯。
客戶端和服務器之間。
客戶端和服務器之間存在通信通道。如果有一個竊聽者在監聽通信,則客戶端哈希可以使密碼洩漏更加困難,因為竊聽者必須從其哈希中恢復原始密碼。
但是,此漏洞是基於不安全的通信渠道的前提。實際上,有些協議的存在試圖準確地解決這個問題。他們的主要任務是在不安全的通道上建立安全通道。最著名且部署最廣泛的示例是SSL / TLS,它比客戶端哈希提供更多的功能和更好的安全性。更好的工具。
服務器。
如果服務器被黑客攻陷,則用戶信息可能會在服務器上洩漏。如果用戶密碼以明文形式存儲,則黑客可以從數據庫中獲取用戶密碼。這就是為什麼今天大多數服務器不這樣做的原因。相反,他們存儲密碼的哈希值,以使黑客無法輕易地從其手頭的信息(即哈希值)中恢復原始密碼。在客戶端計算的哈希值。但這是嚴重錯誤的。在這種情況下,散列本身變成了密碼等效項。黑客可以通過簡單地移交哈希而不反轉哈希來通過身份驗證。黑客的目標不是反轉哈希,而是闖入您的帳戶。重要性在於服務器對客戶端數據的驗證過程,而不是數據是哈希值。因此,客戶端哈希的好處在這裡微不足道,服務器也必須重新哈希。
總而言之,客戶端哈希在以下方面很有幫助保護用戶信息,但該保護很大程度上適用於通信通道。由於我們在那裡有更好的方法(SSL / TLS),因此客戶端哈希的應用受到了極大的壓制。這根本不是解決當前任務的最佳工具。
優良作法是先在客戶端進行哈希處理,然後對密碼加鹽並在服務器端再次進行哈希處理。這是針對中間攻擊中人的額外防護層。 SSL是第一層,但是Snowden的啟示明確表明SSL可以相對容易地被NSA等組織破壞。
客戶端密碼散列有什麼優勢?
那麼,密碼不會以明文形式通過網絡發送。但是登錄時確實應該使用TLS加密,所以密碼監聽應該不是問題。
另一個原因可能是您不希望服務器永遠注意用戶密碼,即使是一微秒也要知道。這意味著您在註冊時為服務器提供了密碼哈希,然後使用該密碼哈希登錄。不幸的是,這並不能解決任何問題:登錄帳戶的共享機密現在是哈希,而不是密碼。當您了解哈希值後,就可以在不知道實際密碼的情況下登錄(因為服務器也不知道該密碼)。
由於您正在談論Web應用程序...
在數據庫中,我們有一個表調用dbo.useracc,我們正在存儲這些哈希密碼
用戶密碼- ------- ---------- user1 5f4dcc3b5aa765d61d8327deb882cf99user2 202cb962ac59075b964b07152d234b70user3 098f6bcd4621d373cade4e832627b4f6
和我們在Web應用程序中的登錄功能類似
如果(用戶== $用戶名和密碼== $通行證){return auth.token}
比方說,攻擊者成功入侵並竊取了數據庫並保存了dbo.useracc數據。現在,他有了我們的哈希密碼。
如果您的登錄哈希過程存儲在客戶端中,攻擊者仍然可以通過使用HTTP POST方法更改密碼字段來發送,從而使用哈希密碼訪問您的帳戶。您的哈希密碼,他仍然可以登錄。請記住,您的應用程序數據最終會在經過哈希檢查後通過POST方法與服務器進行通信。
但是,如果哈希過程在服務器中,那又是另一回事了。
$ pass = md5.hash($ pass); if(user == $ user和password == $ pass){return auth.token;}
如果黑客使用哈希密碼登錄,則將使用哈希密碼來檢查哈希密碼。
在這種情況下,假設攻擊者發布
$ user = user1 $ pass = 5f4dcc3b5aa765d61d8327deb882cf99
在服務器端執行$ pass = md5.hash(5f4dcc3b5aa765d61d8327deb882cf99 ),它將返回“ 696d29e0940a4957748fe3fc9efd22a3”,這將返回錯誤的語句。
這是為了防止攻擊者成功竊取數據庫數據,並嘗試使用哈希密碼通過Web應用程序進行訪問。當然,如果攻擊者通過字典攻擊成功地對暴力破解/破解了哈希,那麼攻擊者仍然可以入侵這些帳戶。但是,如果密碼在破壞系統後是一個好的密碼,則黑客需要更長的時間,並且服務器管理員可以重置密碼並通過電子郵件向用戶發送電子郵件。企業。在企業中,將有數據庫管理員和開發人員。他們是不同的角色。現在,為了防止員工用戶訪問敏感數據,他們需要同時訪問應用程序和數據庫才能訪問數據。當然,您可能會爭辯說,DBA仍然可以通過數據庫本身來更改數據庫數據,但是開發人員無法訪問它,並且更容易確定攻擊的來源。這是關於訪問控制權,並最大程度地降低風險和威脅。
正如@Cyker指出的那樣,儘管該主題有一些具體的洩漏點,但這裡的討論還是有點輕快……我想補充一點我沒有提到的問題。
如果您盡快對哈希進行哈希處理,就可以減少意外將明文密碼傳遞到不應傳遞的地方的編程風險。我們已經採取了安全字符串和安全數組之類的措施,試圖盡快銷毀明文。在獲得密碼的那一刻,散列是另一種類似的措施……隨著代碼的演變等,風險似乎仍在降低。
我只是寫了一個小小的C#“ Box”, SecureString清除文本並立即對其進行哈希處理---這樣,我只知道它永遠不會被記錄或傳遞給我不希望的庫。這與協議無關,它只是程序員坐在這裡看著密碼而已---我不想碰它! (在某些方面,它仍然是等效的密碼,但至少立即被愚蠢地掩蓋了,就像在鏈接的方法調用中移動右括號並將明文傳遞到錯誤的位置一樣。而且仍然沒有隱藏安全數組。) >
我打算以權衡明確的目的加入客戶端哈希機制。讓我們看看這對我們有何好處:
客戶端:無改進。
在傳輸中:如果SSLstrip最終以明文形式傳輸密碼,則保護密碼。但是,如果實施了HSTS,那麼大多數人會說SSLStrip將不起作用。是嗎?否。
在進入服務器時:最後,我們看到了最大的好處。如果有人破壞了服務器怎麼辦?如果他們只是啟動Wireshark / TCPDump並導出服務器的私鑰,他們將獲得連續的明文密碼流。現在,他們可以坐在網絡上幾個月,而對於高容量的服務器(每月有數百萬的用戶註冊),他們將遇到大量的純文本漏洞。當然,這是假定為服務人員獲取密碼比在他們的服務器上擁有RCE更有價值。
在服務器上:無需運行就可以提高性能對每個傳入的密碼進行bcrypt加密,這將在客戶端上分擔一些計算成本,而不會引入任何新的漏洞。對於服務器管理員和硬件成本來說,這似乎是一件好事。
看起來,最佳實踐似乎是將密碼哈希合併到客戶端,除非它為用戶創建了難以忍受的頁面加載時間用戶。
我同意,如果可以使用SSL / TLS,則限制客戶端哈希處理以保護身份驗證過程的優勢。但是,如果攻擊者可以訪問存儲的哈希(此過程之後),則SSL / TLS不能解決針對定制硬件攻擊的漏洞。諸如簡單的鹽漬哈希之類的功能或諸如PBKDF2之類的功能由於對內存的需求低而非常容易受到這些攻擊。受這些方案保護的密碼破解既便宜又快速。至少這是密碼哈希處理的主要問題之一。通過使用密碼散列方案(例如Scrypt,Argon2或Catena)來保護自定義硬件攻擊,服務器的硬件要求急劇增加。因此,實際上,服務會降低內存硬度或切換到易受攻擊的方案。客戶端哈希可以幫助解決該問題。當客戶端計算這些昂貴的(內存硬性)功能時,服務可以使用它們而無需更好的硬件。
因此,現代密碼哈希方案可以委派最昂貴的(內存硬性)部分該功能的客戶端。此功能稱為服務器救濟,由Argon2和Catena提供。
結論:使用現代的密碼散列方案(該漏洞不太容易受到自定義硬件攻擊),將來會增加或至少應該增加客戶端散列的使用,當然還有SSL / TLS
我認為客戶端哈希具有一個弊端和一個缺點:
pro:在dns /網絡釣魚/任何情況下,您都隱藏密碼,這對用戶很有用,因為大多數人會重用密碼在幾個服務上。正如其他開發人員所說,這對您自己的安全無濟於事。
cons:您的服務器未獲取密碼,從而避免了諸如警告用戶密碼強度的問題。我知道有人會說這可以/應該是客戶端,但是當您有多個客戶端時,集中服務器端會很好。
我認為客戶端被黑客入侵的可能性比服務器端更高。 (因為有一些IT專家照顧服務器)。如果您的計算機已經被黑客入侵。用來散列密碼的客戶端算法也可以被黑客竊取。盡快,您的算法不再是秘密。我認為,它變得毫無用處。