2009-08-10 52 views
0

我正在爲一個客戶開發一個Asp.NET網站,並且希望確保我使用安全的身份驗證方案。安全用戶身份驗證 - 我是否正確地執行此操作?

在我的用戶表中,我有一個驗證哈希列,計算結果爲sha1(salt + username + password)。該網站正在通過HTTPS提供服務。要登錄,用戶通過HTTPS提交他們的名字和密碼。 Web服務器計算散列值,並將其與數據庫存儲值進行比較以進行認證。

這聽起來合理安全嗎?我跑過這個計劃,經過我的一個朋友,他說它很容易受到惡意的系統管理員的攻擊。他說我應該做以下事情:

  • 服務器在每次登錄頁面服務時指定一個獨特的salt。
  • 在提交之前,通過JavaScript在客戶端上密碼哈希密碼。
  • 發送此散列進行身份驗證,但不是密碼。
  • 做一些奇怪的垃圾,我不明白認證哈希。

我該怎麼辦?

+1

你的伴侶爲什麼說它很容易受到流氓系統管理員的攻擊?通常這是非醃製或明文密碼的問題。我想知道他的推理是什麼...... – davewasthere 2009-08-10 16:35:55

回答

7

不要重新發明輪子,只需使用.Net Membership

+0

我以前參與過使用此項目的項目。我記得有些事情讓我避免了這個解決方案。但我不記得那是什麼。有些事情太僵化了。 但是,閱讀您的鏈接表明我的信息不正確。 :) – recursive 2009-08-10 16:37:19

2

如果您在每次提供登錄頁面時更改salt,如何將其與使用不同鹽進行散列的數據庫中的內容進行比較?

你在SSL下,你可以發送憑據的自由文本,因爲該行已被加密,然後將規則應用於鹽/哈希你的密碼比較服務器端。這樣沒人知道你是如何加密你的密碼的。將信息存儲在客戶端JavaScript只是將這些信息發送出去。

除此之外,你的方法看起來是正確的。我假設你需要一個自定義的解決方案,而不是出於任何原因內置的解決方案。

+0

我猜他的鹽將存儲在一個單獨的列。否則,重新驗證會非常棘手。 – davewasthere 2009-08-10 16:37:05

3

閱讀:
Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes

我們學到了什麼?
...如果是2007年,彩虹桌攻擊將您置於火中,我們知道您應該回到1975年,等待30年後再嘗試設計密碼散列方案。
...我們應該在安全領域諮詢我們的朋友和鄰居,以獲得密碼方案的幫助。
...在密碼散列方案中,速度是敵人。我們瞭解到MD5是爲了速度而設計的。所以,我們瞭解到MD5是敵人。
...如果我們想要安全地存儲密碼,我們有三個合理的選項:PHK的MD5方案,Provos-Maziere的Bcrypt方案和SRP。我們瞭解到正確的選擇是Bcrypt。

關鍵點的位置:

  • 不管你做什麼,不要試圖從頭開始構建自己的身份驗證碼
  • Bcrypt是散列密碼的最佳選擇。
+1

嗯,這是一篇很好的文章,直到我看到這個 - 「你可以使用挑戰 - 響應方案,雙方使用數學問題向對方證明他們知道密碼,但雙方都不通過線路發送密碼。方案很好,但除非雙方都能訪問明文密碼 - 換句話說,服務器必須將其存儲在明文中,否則它們不起作用。「他在這裏絕對是錯的。質詢/響應系統不需要服務器以明文方式存儲密碼。 – 2009-08-10 18:32:45

4

首先,如果用戶通過HTTPS連接,那麼通過網絡發送密碼到服務器應該沒有問題。

否則,確保你的鹽很長,並使用體面的熵來隨機。由於SHA-1是considered broken,所以請確保您使用SHA-2而不是SHA-1。

2

你的朋友是正確的斷言鹽應該是唯一的,但他在處理鹽方面是錯誤的。

  • 哈希密碼前 提交通過JavaScript客戶端上的獨特的鹽。

,需要你要麼使用相同的鹽爲大家還是知道用戶是誰,所以你可以把他們自己的獨特的鹽。鹽不應該離開服務器。

+0

它不應該是一個用戶鹽。它應該每一次都是獨一無二的。 – recursive 2009-08-10 16:50:18

+0

@recursive:如果鹽每次都不同,用戶如何進行認證?如果用戶名/密碼/ salt對用戶來說不完全相同,那麼散列將永遠不匹配存儲在數據庫中的內容。 – MyItchyChin 2009-08-10 18:04:23

4

這聽起來合理安全嗎?我 運行這個計劃通過我的一個朋友, ,他說它很容易受到 邪惡的系統管理員。

直接發送密碼總是有點危險。即使你使用SSL。如果這就是他所指的那麼他就是對的。我不會說它很脆弱,只是不是最安全的方法。

  • 服務器在每次登錄頁面提供時指定一個獨特的salt。
  • 提交之前,通過javascript 將密碼散列在客戶端上的唯一鹽。
  • 發送此散列進行身份驗證,但不是密碼。
  • 做一些奇怪的垃圾,我不明白認證哈希。

這聽起來像是他提出了一個與SSL結合的挑戰 - 響應方案。這是一個很好的方法,但讓我逐步解釋清楚。

註冊後,密碼通過SSL發送到服務器。這應該是密碼直接發送的唯一時間。服務器生成一個鹽並存儲以下哈希:

hash = sha1(password + salt) 

服務器還應該存儲salt。

當客戶端訪問登錄頁面時,服務器應該在具有ID和挑戰值的表中生成記錄。然後服務器應該將ID,存儲的鹽和挑戰值發送到客戶端。

當客戶端就可以登錄,你應該有一個javascript函數產生一個挑戰,以及像這樣的哈希:

hash = sha1(sha1(password + server_salt) + server_challenge + client_challenge) 

客戶端應當提交的哈希值,該server_saltid和client_challenge值。然後,服務器計算哈希像這樣:

hash = sha1(stored_hash + server_challenge + client_challenge) 

如果哈希匹配用戶進行身份驗證,在任何情況下,面臨的挑戰記錄應予刪除。