注冊登錄原理及密碼安全問題
安全性,是一個公司生死存亡的關鍵,華為、騰訊和阿里等公司,都有大量的技術人員來保障業(yè)務安全。平時工作中,一旦遇到安全問題,必須立即高優(yōu)先級處理。安全攻防,是一個動態(tài)的博弈,沒有攻不破的防守,也沒有防不住的進攻。
今天,我們來簡要聊一聊注冊和登錄。注冊APP成功后,就可以登錄。看似簡單的操作,其實蘊含了很多密碼安全的問題。

當你注冊APP,填寫用戶名和密碼,點擊提交后, APP后臺肯定需要“存儲你的用戶名和密碼”,而當你輸入用戶名和密碼進行登錄時,APP后臺就能判定你輸入的用戶名和密碼與當時注冊的用戶名和密碼是否匹配,從而確定是否讓你登錄。
那么,有沒有思考過這個問題:APP后臺開發(fā)的程序員GG們,能偷窺到你的密碼嗎?他們會盜用你的賬號和密碼進行登錄嗎?黑客攻擊APP后臺后,能盜用你的賬號和密碼嗎?
顯然,這是不能允許的。沒有辦法在道德和法律的規(guī)范下嚴格禁止這樣的行為,那就要從技術機制上禁止,要確保即使在數(shù)據(jù)庫和程序代碼被盜走的情況下,壞人也無法破解密碼。
1.密碼直接明文存儲
如果在APP后臺數(shù)據(jù)庫中直接存儲用戶名和密碼,那么黑客可就要在睡夢中笑醒了:

當年CSDN真是搞笑搬地存在:

2.密碼加密存儲
自然地,我們想到對密碼進行加密存儲:

這種方式也挺業(yè)余的,既然能加密,就有辦法解密,同樣存在密碼被盜的風險,如果APP后臺能以某種方式還原密碼,那肯定就是流氓系統(tǒng)。我們也有這樣一個常識:當用戶忘記密碼后,正確做法不是APP后臺告訴用戶密碼是多少(因為APP后臺壓根就不應該知道用戶的密碼),而應該讓用戶重新設置密碼。
3.密碼直接哈希存儲
哈希函數(shù),單向散列,且?guī)缀醪粵_突,故可以考慮對密碼進行哈希變換后存儲,如下:

如此一來,從理論上講,即使哈希值yyyyyy被盜走,別人也難以還原成原來的abcd123了,因為哈希函數(shù)不可逆。這樣貌似就實現(xiàn)了密碼的安全存儲,不過,有點太天真了。
如果數(shù)據(jù)庫和程序代碼被盜,從理論上講,難以用yyyyyy反推出密碼abcd123, 但黑客可以用彩虹表攻擊,分分鐘就能破解出密碼abcd123, 彩虹表攻擊的圖示如下:

簡單解釋一下:黑客通過長期積累,對一些常用的字符串進行哈希,得到哈希值,形成一張很大的資料表,一旦黑客盜走數(shù)據(jù)庫中的密碼哈希值yyyyyy, 就可以在資料表中進行查找,很快就能知道密碼是abcd123, 這個資料表,就是所謂的彩虹表。
理論上不可反解的哈希函數(shù),被狡猾的黑客給“破解”了,并且得到了密碼。
4.密碼多次哈希后存儲
有的朋友可能覺得彩虹表能實現(xiàn)攻擊,主要是因為只用一次哈希,那么多加幾次哈希,是不是就解決問題了呢?
顯然不是。多次哈希后,一旦黑客拿到你多次哈希的程序代碼和數(shù)據(jù)庫,便可以構造多重彩虹表,分分鐘破解密碼:

5.固定鹽值的哈希存儲(無需存鹽)
思考一下,現(xiàn)在的問題是,要抗彩虹表攻擊,可以考慮這么做:
P = hash(user + hash(password)) 此處的user就是用戶名,用作鹽值。這樣,就增加了黑客的破解難度,因為黑客需要針對每個user做一張?zhí)囟ǖ亩夭屎绫恚庞锌赡芷平狻?/span>
即便如此,在攻擊一些重要user時, 黑客可能感覺值得嘗試一下,所以,用固定鹽還是存在較大風險。
6.隨機鹽值的哈希存儲(需要存鹽)
既然固定鹽值不好,那就用隨機鹽吧,于是可以考慮這么做:
P = hash(salt + hash(password)) 這個隨機鹽salt,需要存儲在APP后臺數(shù)據(jù)庫中??蓡栴}是,APP和APP后臺需要使用相同的隨機鹽,那么APP是怎樣獲取APP后臺的隨機鹽呢?這又涉及到一系列的加密算法(RSA和AES)和秘鑰管理問題,在實際系統(tǒng)中,有些公司就是這么做的。
隨機鹽的引入,可以讓彩虹表失效,黑客只能“望鹽興嘆”。
7.bcrypt存儲(無需存鹽)
有沒有更簡潔且安全的做法呢?有的,用bcrypt吧。我始終覺得,bcrypt這個名字不太好,應該叫bSHA, 其實也不用糾結名字。bcrypt是一個帶隨機鹽的哈希函數(shù),在哈希值中,又攜帶了鹽的信息,所以,在APP后臺,就能從哈希值中解析出APP端使用的隨機鹽,所以,該隨機鹽不需要被APP后臺數(shù)據(jù)庫存儲。使用bcrypt后,注冊登錄邏輯圖如下:

而且,bcrypt是一個相對較慢的哈希函數(shù)(比如設置1s),這就大大增加了黑客暴力破解的難度。這里要說明的是,APP端的bcrypt慢,但APP后臺對應校驗函數(shù)并不慢,所以不會影響APP后臺服務的性能。
掃碼登錄原理
實際上,用戶在APP上登錄后,會獲取一個登錄態(tài)票據(jù)(session key, 一般簡寫為skey),在后續(xù)的每次操作中,用戶不必再輸入密碼了,APP自動攜帶登錄態(tài)票據(jù),此時APP后臺進行登錄態(tài)票據(jù)校驗就可以了,也提升了便利性和安全性。
最后,我們來看下掃碼登錄的原理, 網(wǎng)頁上的二維碼圖如下:
用戶登錄APP后,獲取到了登錄態(tài)票據(jù)skey, 然后用戶利用APP對網(wǎng)頁上的二維碼進行掃描,獲取隱藏在二維碼中的token, 并提交到后臺,實現(xiàn)掃碼登錄,掃碼登錄的邏輯圖如下:

這個圖一目了然,不需要具體解釋每一步。值得注意的是,步驟6執(zhí)行完后,步驟3中的輪詢才會知道網(wǎng)頁token和APP端的userID/skey在后臺建立了關聯(lián),此時網(wǎng)頁的掃碼登錄也就成功了。
這篇文章,談的是自建賬號體系的注冊和登錄,在后面的文章中,我們會聊第三方賬號體系的登錄,到時見。
關注數(shù):10億+ 文章數(shù):10億+
粉絲量:10億+ 點擊量:10億+
微信群管理員請掃描這里
微信群管理員請掃描這里
喜歡本文的朋友,歡迎關注公眾號 程序員哆啦A夢,收看更多精彩內容
點個[在看],是對小達最大的支持!
如果覺得這篇文章還不錯,來個【分享、點贊、在看】三連吧,讓更多的人也看

