
英文 | https://betterprogramming.pub/21-best-practices-for-handling-passwords-in-web-applications-7b2d7a66378f
翻譯 | 楊小二
哪個做法更聰明?是打破鎖還是偷鑰匙?
當然,你可以建立一個堅固的鎖,但是,如果你不能保護鑰匙,那就沒有用了!
密碼就像你系統的鑰匙。是以,如果你是一個真誠的Web開發人員,那麼,確定其實力是你的責任!
今天,我們一起來讨論一下有關密碼的一些最佳做法。許多例子正在醞釀之中,請系好安全帶!我們要準備開車出發了,老司機帶你上路。
1、優先使用長密碼而不是困難密碼
鼓勵使用者選擇更長的密碼,而不是使其更難記住。
輕松+長>困難+短
這是因為大多數黑客攻擊不是由試圖猜測密碼的人完成的,通常是由運作循環的計算機完成的。
機器不在乎難度。是以,請使用更長的密碼!
2、永遠不要通過電子郵件發送普通密碼
不幸的是,這是開發人員中非常普遍的錯誤。以純文字形式發送密碼比你想象的要普遍得多。
近40%的人至少每周一次忘記密碼。
是以,他們要做的是重設密碼并在電子郵件中找回普通密碼。
任何電子郵件都通過各種伺服器發送。如果其中之一受到威脅,那麼你就有麻煩了!是以永遠不要這樣做!
備選擇方案:
- 文字訊息
- 一次密碼
- 加密電子郵件服務
- 密碼管理者
3、使用HTTPS進行身份驗證相關頁面
這是顯而易見的。盡早安裝有效的SSL證書!如果你有任何限制,請至少對身份驗證頁面執行此操作。
這不僅對安全性很重要。這對于在使用者之間建立信任也很重要,并且有助于SEO。
HTTPS通過加密提供隐私。詳細内容不在本文的讨論範圍之内,但如果你有興趣,你可以點選打開以下的網址資源進行學習。
資源:https://howhttps.works/
4、防止字典密碼
詞典密碼是最常用密碼的清單。密碼破解者發現密碼更容易破解。他們通常首先經曆這些。
這是100000個最常用密碼檔案的清單-以此作為參考并對其進行檢查。
1000萬個字典密碼清單位址:https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt
5、防止順序密碼
人們使用一些常見的序列作為密碼很容易預測。
不好的例子:
qwertyuiop -> top row of keyboard
asdfghjkl -> middle row of keyboard
zxcvbnm -> bottom row of keyboard
123456 -> numeric digits in sequence
這些對于使用者的手指來說比較容易,但是對安全性卻不利。防止使用者提供這些内容。
6、防止重複輸入密碼
同樣,重複的密碼在使用者中非常普遍。它們通常很容易記住,是以很容易猜到。
不好的例子:
aaaaa1111
bbbbb22222
在前端檢測到這些,并勸阻人們不要使用它們。
7、不要在資料庫中存儲普通密碼
這意味着有權通路資料庫的任何人都可以輕易地破壞所有使用者帳戶。
切勿将密碼直接存儲在資料庫中。
實作某種加密。不難,為什麼不呢?
8、使用哈希函數而不是加密函數
談到加密...不使用加密功能,如SHA1,SHA2,MD5等等,這些都是設計來處理大型資料集的通用Hash函數。
始終使用bcrypt。随着bcrypt可以确定散列函數将有多貴定。下面的代碼顯示了它的簡單程度!
由于密碼不是一個很大的資料集,是以非常适合此用例。
資源:https ://codahale.com/how-to-safely-store-a-password/
9、懲罰使用者
為登入不成功時,可以嘗試引入一種懲罰系統。如果某人在嘗試了10或者15次後仍無法登入,可以懲罰他們大約一小時後再登入。
10、考慮實作第二個使用者名
在大多數網站(如Facebook)上的userName,如果你傳到其個人資料,便可以從URL輕松了解使用者的身份,它可以使破解更容易。
如果你确實關心安全性,則應考慮userName為使用者實施第二個安全性。每個人都有不同的目的。
已知的使用者名:
- 識别一個人
- 搜尋資料
- 網上身份
未知的使用者名:
- 這将僅用于身份驗證。
- 隻有使用者會知道。
11、适當的UI設計
盡管可以在後端檢查強密碼,但是,你應該考慮實作某種前端驗證。
禁用送出按鈕直到輸入有效密碼為止。以下是檢查密碼強度的示例。
let strongPassword = new RegExp('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{8,})')
let mediumPassword = new RegExp('((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{6,}))|((?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])(?=.{8,}))')
const checkPasswordStrength = (inputPassword) => {
if(strongPassword.test(inputPassword)){
console.log('Password is strong!')
}else if(mediumPassword.test(inputPassword)){
console.log('Password strength is medium!')
}else{
console.log('Password is weak!')
}
}
const inputPassword = 'Some Password Given By User'
checkPasswordStrength(inputPassword)
資源: 帶有JavaScript的密碼強度檢查器:https://www.section.io/engineering-education/password-strength-checker-javascript/
12、引入延遲
每次登入失敗後,将延遲五秒鐘,你的使用者将不會感覺到它,但是攻擊者會感到痛苦。
如果攻擊者試圖猜測使用者的密碼,他們将失敗很多次。這将使攻擊的數量級更加困難,是以不太可能在合理的時間内成功。
資源:這是一個資訊性的線程:https://security.stackexchange.com/questions/94432/should-i-implement-incorrect-password-delay-in-a-website-or-a-webservice
13、勸阻替代
有人認為使用C0mpl3x而不是Complex作為密碼更安全。但猜猜怎麼了?其他人也知道這一點!
是以,不鼓勵你的使用者使用這種類型的密碼,破解者無論如何都會替換掉這些替代品,是以他們隻會使密碼變得複雜而沒有任何功能。
14、兩方面身份驗證
這與密碼不直接相關,但與安全性相關。考慮為你的Web應用程式實施兩因素身份驗證。
15、密碼短語更好
有兩種類型的人:一種是那些相信複雜詞組密碼會更好,另一種是那些相信長密碼短語會更好。
嗯,根據FBI的說法,較長的密碼短語更适合作為密碼,因為它們很難破解。
這是一個比較:
資源: https : //www.zdnet.com/article/fbi-recommends-passphrases-over-password-complexity/
16、分層
添加多層安全保護-不僅依賴于前端驗證或後端驗證。嘗試采用多個安全級别,以便存在多個故障點。
你永遠都不知道可能出什麼毛病!
17、幾次不正确的嘗試後鎖定帳戶
這是相當明顯的,跟蹤使用者是否嘗試登入帳戶并反複輸入錯誤。
阻止或鎖定這些帳戶并運作其他驗證。但是,這應取決于你的用例。
18、保持挑戰性問題不可預測
如果帳戶被鎖定,則某些系統會使用質詢問題添加第二層。
具體那些問題不可預測!例如,“你媽媽叫什麼名字?” 這不是一個很好的問題,可以在使用者的社交媒體頁面上找到它!
好問題的答案應該是這樣的。
- 即使幾年後,也相當容易記住。
- 包含成千上萬個可能的答案,是以不容易猜到。
- 這不是社交媒體上經常發現的話題。
- 有一個永不改變的答案(你喜歡的顔色或夢想中的汽車可能會随着時間而改變)。
示例:你的童年英雄是誰?
資源:很好的挑戰性問題
19、避免密碼輪換
這是一個有争議的。據說,你應該強迫使用者在90天後修改一次其密碼-認為這是破解密碼所花費的時間。
使用者中有一些不良的行為,因為他們通常希望避免頻繁更改密碼,是以到處都使用相同的密碼!
20、鼓勵使用者在密碼中使用空格
密碼中的空格是一件好事。不幸的是,許多使用者沒有利用這一點。
鼓勵他們使用空格-它會自動建立更安全且易于記住的密碼!
21、經驗法則
如果你走得這麼遠并且感到無聊,并且不想記住所有這些要點,那麼,讓我為你簡化一下。隻要記住一件事!使用長密碼,你應該可以記得住了。
總結
大多數的時候!你已經做到了!這些準則可能并不适合所有用例,但我希望你學到了一兩個你認為有用的做法!
祝你有美好的一天,我的朋友!
感謝你的閱讀。
學習更多技能
請點選下方公衆号