2012-02-08 85 views
4

我知道強制密碼在用戶創建它們一段時間後過期並不是Devise邏輯的一部分,我打算編寫自己的代碼來實現這一點。防止密碼重複使用Devise

它也看起來像強迫用戶不要重用最後一個X(在我的情況下10)密碼將需要手動編碼。

我的想法是,我會創建類似user_passwords表的東西,並在我的代碼中使用邏輯來確保新密碼與該用戶的表中的任何內容不匹配。同時,我會將新密碼插入表中,除非該用戶已有10條記錄,這意味着我會用新值覆蓋最早的那條記錄。表結構將是這樣的:

user_passwords

  • USER_ID
  • encrypted_pa​​ssword
  • created_at

如果任何人有一個更好,更優雅的解決方案來處理這個問題,我感謝你。

+1

我認爲「不要使用任何你最近的10個密碼」是有些武斷的,除非你有一個具體的商業原因。您可以輕鬆執行「不要使您的新密碼與舊密碼相同」。現實情況是,密碼很難記住,而您將要驅動的行爲是讓用戶在便籤上記下密碼。 – 2012-02-08 01:11:47

+0

這是客戶的實際需求。這是一家金融公司。 – 2012-02-08 01:15:41

+0

然後,我不認爲有比你提出的更優雅的解決方案... – 2012-02-08 01:19:17

回答

2

devise_security_extension似乎爲我需要的。

但是,目前它不支持Devise 2.0或更高版本。我遇到了一些問題,必須將我的設計降級到1.5.3。根據他們留言板上的評論,他們目前正致力於將寶石移植到Devise 2.0兼容版本。

我已經爲它的password_expirable和password_archivable模塊給了它一個旋轉。一切似乎都按預期工作。

它還支持secure_validatable,session_limitable和expired,前兩種我可能會在不久的將來使用。

+0

我想覆蓋session_limitable行爲,因爲我只需要http請求的行爲。任何想法.. – Prem 2013-07-17 05:17:03

4

我知道強制密碼在用戶創建它們一段時間後過期並不是Devise邏輯的一部分,我打算編寫自己的代碼來實現這一點。

在實踐中,安全相關的研究發現這是一個壞主意。那是因爲你在每次變更時都會收益遞減。也就是說,隨着用戶嘗試遵守該策略,密碼開始強勁並且隨着時間的推移變弱。參見Peter Gutmann的Engineering Security和第7章,密碼

從書中,其他愚蠢的東西包括複雜性要求。 (在您反對之前,請閱讀本書的相關部分)。


...創造這樣一個user_passwords表並使用邏輯在我的代碼,以確保新密碼不匹配任何在該表中爲該用戶。

而且一旦你閱讀了這章,我將能夠問:爲什麼你允許用戶首先選擇弱/受傷/破碎的密碼?當Mark Brunett's list of 10 million leaked passwords結合:)


防止密碼重用那些60個KB布隆過濾器看起來強大有用...

那將傷害的重用是跨站點密碼重用。布朗,布拉肯,佐科利和道格拉斯在Generating and Remembering Passwords(應用認知心理學,第18卷,第6期,第641-651頁)中指出,這些數字約爲70%。 Das,Bonneau,Caesar,Borisov和Wang在​​報告了45%左右的數字。請注意,魔鬼網絡研究必須破解密碼,所以這個數字可能會更高,因爲他們無法恢復所有的密碼

爲了使重複使用成爲一個更嚴重的問題,用戶必須記住約25個不同網站的密碼Das,Bonneau,Caesar,Borisov和Wang在​​。

幾年前,我甚至被燒傷了。我在兩個低價值賬戶上使用了相同的密碼。然後GNU's Savannah被黑客攻擊,攻擊者可以使用恢復的密碼來破壞一個已用過的電子郵件帳戶。

現在我只需要生成一個很長的隨機字符串就可以了。我甚至不會爲大多數網站寫下它們。當我需要再次訪問網站時,我只需要完成恢復過程。

+0

可悲的是密碼恢復過程是窮人的雙因素認證。 – zaph 2016-07-11 13:46:57

-1

devise_security_extension不導軌5爲我工作,我創建了定製:

  • 創建遷移並添加一個額外的列,如: add_column:用戶:old_passwords,:文本
  • 在模型中添加兩​​個回調:after_save的:cache_old_pass和before_save:verify_old_pass

  • 創建回調的方法:

    private 
    def verify_old_pass 
        if self.encrypted_password_changed? 
        old_passwords.to_s.split(',').each do |pass_encrypted| 
         if Devise::Encryptor.compare(self.class, pass_encrypted, password) 
         errors.add(:base, 'Your password cannot be previous up to 3 back') 
         return throw(:abort) 
         end 
        end 
        end 
    end 
    
    def cache_old_pass # cache last 3 passwords 
    if self.encrypted_password_changed? 
        update_column(:old_passwords, ([self.encrypted_password] + old_passwords.to_s.split(',')[0, 3]).join(',')) 
    end 
    end 
    
+0

告訴我們您沒有保存加密或不加密的實際密碼,那完全是不負責任的。當攻擊者獲得數據庫時,他也會得到加密密鑰。 – zaph 2016-07-11 13:39:12

+0

這不是保存未加密的密碼,它保存由設計生成的歷史密碼和由設計驗證(沒有被黑客入侵) – 2016-07-15 15:32:41

+0

所以我猜Devise :: Encryptor是錯誤的,因爲它似乎執行散列,而不是加密 - 這是好消息。如果[docs](http://www.rubydoc.info/gems/devise/Devise/Encryptor#digest-class_method)解釋到底發生了什麼,但我猜你付出了什麼,那將會很好。錯誤的命名應該受到懲罰,但是我們只是編碼猴子,而不是專業人員。 – zaph 2016-07-15 15:50:33

0

Here是Devise gem的文檔如何禁用以前使用的密碼?