所有需要登入的網站,都會提供"找回密碼"的功能,防止使用者忘記密碼。
正確設計這個功能,保證安全可靠,並不簡單。下面就是安全專家 Troy Hunt 給出的設計指南。
一、如何儲存密碼
一個網站要想保證密碼安全,第一步就是以正確的方法儲存密碼。一般說來,密碼有三種儲存方式。
(1)明文儲存
"明文儲存"就是使用者的密碼原文不動地寫入資料庫。這種方式最不安全,極易洩漏,應該嚴格禁用。
(2)加密儲存
"加密儲存"就是使用金鑰,將密碼加密後,以密文儲存進資料庫。這種方式雖然有一定的安全性,但是終究還是可以用金鑰還原密碼。因此,還是存在洩漏的可能,也不推薦使用。
(3)雜湊儲存
"雜湊儲存"就是對密碼使用雜湊演算法,將雜湊值儲存進資料庫。為了增加隨機性,防止彩虹表這一類的工具,計算雜湊的時候,每個使用者都有一個不一樣的鹽值(salt),也會同時儲存進資料庫。
雜湊是單向運算,無法還原,所以即使雜湊值洩漏,一般來說,也不會暴露使用者的原始密碼。
第一條規則:密碼永遠都要雜湊儲存。
二、密碼重置
如果密碼是雜湊儲存,使用者一旦忘記密碼,網站也無法知道原始密碼是什麼,只能讓使用者重置密碼。
第二條規則:找回密碼就是讓使用者重置密碼。
重置密碼又有兩種做法。有的網站先自動改成一個隨機密碼,然後再讓使用者登入後自己改掉。這樣做的風險在於,你必須把隨機密碼告知使用者,通過郵件或簡訊,這個過程中就有可能洩漏。
第三條規則:重置密碼的時候,要給出一個連結,讓使用者到網頁上自己修改密碼。
重置連結由於是明文傳播,而且直接修改密碼,所以必須有失效時間。一般來說,可以設成10分鐘失效。
三、使用者名稱還是郵件地址?
重置密碼之前,必須知道重置誰的密碼。這時需要使用者提供,註冊時的郵件地址。
第四條規則:重置密碼之前,如果使用者提供了錯誤的郵件地址,不要提示他。
這是因為如果提示了,資料庫不包含某個郵件地址,就可能像下圖那樣,洩露使用者的隱私,被釣魚者利用。
正確的做法是,不管使用者輸入什麼郵箱,都向該郵箱發郵件。在郵件裡說明,有人嘗試重置密碼,但是他輸入的郵箱不在資料庫裡面。
如果不是採用郵件地址,而是根據使用者名稱識別使用者,就沒有辦法不提示,某個使用者名稱是否存在。某些人的使用者名稱非常特殊,一旦知道該使用者名稱存在,就幾乎可以肯定是該人註冊的。
第五條規則:重置密碼的時候,識別使用者最好依靠郵件地址,而不是使用者名稱。
四、過濾使用者
為了防止機器人攻擊,進入重置密碼之前,最好加上 CAPTCHA 識別。
此外,還要防止一種情況:張三知道李四的郵箱,然後使用找回密碼功能,讓系統給李四發出重置密碼的郵件。
第六條規則:如果條件允許,重置密碼之前,最好請使用者回答一些個人問題,或者採用 2FA 驗證,比如簡訊驗證碼。
最後,不要忘了記錄 IP 地址,在郵件裡面告訴使用者,哪個 IP 地址在申請重置你的密碼。
(完)