2009-10-07 113 views
20

我被要求對內部網站實施一些更改/更新;當他們稱之爲「未來證明」時。如何升級密碼存儲方案(更改散列算法)

我們發現,密碼使用MD5算法散列。 (該系統自2001年以來一直在使用,因此在時間上已足夠)。
我們現在想要將散列算法升級到更強的一個(BCrypt-hash或SHA-256)。

我們顯然不知道明文,密碼和創建的用戶羣一個新的密碼是不是一個選項*)

所以,我的問題是:

什麼是接受的方式來改變散列算法,而無需訪問明文密碼?
最好的解決方案將是一個完全「幕後」的解決方案。

*)我們嘗試;試圖說服他們,我們用「密碼時代」的說法,試圖用咖啡來賄賂他們,試圖與蛋糕,等等,等等賄賂他們,但它是不是一個選項

更新
我所期待的某種解決該問題的解決方案AUTOMAGIC的,但顯然沒有其他的選擇不只是「等待用戶登錄,然後再轉換」。

好了,現在我至少現在還沒有其他可用的解決方案。

回答

24

首先,一個字段添加到數據庫以識別密碼是否被使用MD5或新算法。

對於所有的密碼仍然使用MD5:

- 在登錄過程中,在那裏你驗證用戶輸入的密碼:臨時存儲在內存中的用戶提交的密碼(無安全問題在這裏,因爲它已經在內存某處),並執行通常的MD5散列&與存儲的散列進行比較;

- 如果提供了正確的密碼(與現有的散列值相匹配),請通過新算法運行臨時存儲的密碼,存儲該值,更新新字段以確定此密碼已更新爲新算法。

(當然你只需使用新的算法爲所有新用戶/新口令。)

3

passwordChange時間字段添加到數據庫中。

所有密碼X日之前設置,檢查使用MD5

所有密碼一天後X設置,檢查使用BCrypt或什麼的。

+0

並且當他從MD5登錄到BCrypt時更改用戶的密碼。 – Dennis 2012-11-09 11:15:19

3

您可以將其存儲在散列字段本身(例如「MD5:d41d8cd98f00b204e9800998ecf8427e」)或另一列中,使用哪種算法創建該散列。然後,您必須修改登錄過程以在檢查密碼時使用正確的算法。當然,任何新密碼都將使用新算法進行散列處理。希望密碼最終到期,隨着時間的推移,所有的MD5哈希將被逐步淘汰。

+1

假設您在那時可以訪問明文密碼,您也可以讓登錄過程將密碼「升級」到新的散列算法。 – Craig 2009-10-07 19:50:14

+1

D'oh!當然你可以,而且你應該。 – 2009-10-07 19:55:58

3

既然你不知道明文密碼,也許你應該創建這表明encription版本的字段(如PasswordVersion bit default 0

下一次用戶試圖登錄,使用當前版本的算法校驗散列密碼,就像你今天做。如果匹配,則再次對其進行散列並更新PasswordVersion字段。

希望你不需要PasswordVersion列大於bit。 =)

+0

「希望你不需要比位更大的PasswordVersion列」讓我微笑(+1) – Jacco 2009-10-07 20:06:57

+0

真的,不要假設你這次是正確的。使用'byte'作爲你的PasswordVersion。 – 2011-07-04 13:15:24

+1

只是8試圖使它正確嗎?使它成爲'int',你將得到足夠的空間來設置你自己的錯誤... =) – 2011-07-05 00:30:30

3

您應該更改您的密碼數據庫來存儲3個項目:

  1. 的算法標識。
  2. 服務器在首次計算並存儲密碼哈希時所選擇的隨機鹽字符串。
  3. 使用指定算法連接salt +密碼的哈希。

當然這可能只是一個分隔符一起存儲在一個文本字段:

「SHA256:這-是鹽:此結果,哈希值」

現在你現有條目轉換爲數值與空鹽和老算法

「MD5 ::這 - 是最老的MD5哈希 - 沒有鹽」

現在您有足夠的信息來驗證您現有的所有密碼條目,但您也可以驗證新條目(因爲您知道使用了哪個哈希函數)。您可以將舊條目下一次的現有用戶登錄轉換爲新的算法,因爲你將不得不使用自己的密碼,在此過程中:

  1. 如果你的數據庫表明他們正在使用的舊算法,無鹽,首先驗證通過檢查密碼的MD5哈希值匹配舊密碼。如果不是,則拒絕登錄。
  2. 如果驗證密碼,請讓服務器選擇一個隨機salt字符串,計算salt +密碼的SHA256哈希值,並將新的密碼錶項替換爲新算法salt和hash。
  3. 當用戶再次登錄時,您會看到他們正在使用新算法,因此計算salt +密碼的哈希值並檢查它是否與存儲的哈希值匹配。

最終,在系統運行了適當的時間之後,您可以禁用尚未轉換的帳戶(如果需要)。

對每個條目添加一個隨機salt字符串使得該方案更能抵抗使用彩虹表的字典攻擊。

+0

舊的MD5方案已經使用了適當的哈希。 – Jacco 2009-10-07 21:13:26

+0

我不確定我是否理解你的評論,除非通過「used proper hashing」,你的意思是在用MD5散列密碼之前已經添加了一個salt值。 如果是這樣,升級方案仍然有效,您只需在使用MD5進行驗證時考慮到salt。 – 2009-10-08 15:42:43

5

我不完全確定這個選項,因爲我不是密碼學方面的專家。請糾正我,如果我在這裏有點錯了!

我認爲Dave P.顯然是最好的選擇。

......但是。有一個automagic解決方案 - 自己散列舊的哈希。也就是說,採用當前的哈希,並用更強大的算法再次哈希它們。注意,據我所知,在這裏你不會從散列長度中獲得任何附加的安全性,只有新算法增加的密碼複雜性。

問題是,當然,檢查密碼然後必須通過這兩個散列。你也必須爲evey新密碼做同樣的事情。這是,很好,愚蠢。除非你想使用像Dave P.這樣的解決方案,最終通過新的哈希算法回到單哈希密碼中......在這種情況下,爲什麼還要爲此煩惱呢?

不過,這是一個選項,可以 - (在介紹企業西裝方式,具有相對着臉......當然,你可以使用它在一個華麗的「安全性提高了所有密碼,立即生效!」)立即應用於所有當前密碼,而無需任何逐步遷移階段。

但是,男孩,哦,男孩,稍後有人會有一個很好的笑看這個代碼! :)

+0

這聽起來像我正在尋找的東西。但我不確定'散列哈希'的含義,我認爲我在某些地方看到結果在某些條件下可能是次優的。但我不知道。 – Jacco 2009-10-19 12:27:37

+1

這是一個壞主意,因爲如果在第一個散列中存在衝突,那麼在組合算法中會有衝突。在MD5中有已知的碰撞。 – 2011-07-04 13:17:05

+2

@Richard,爲什麼在這種情況下哈希碰撞很重要? – 2011-07-05 05:40:44