天天看點

注冊登入原理及密碼安全問題

      安全性,是一個公司生死存亡的關鍵,華為、騰訊和阿裡等公司,都有大量的技術人員來保障業務安全。平時工作中,一旦遇到安全問題,必須立即高優先級處理。安全攻防,是一個動态的博弈,沒有攻不破的防守,也沒有防不住的進攻。

      今天,我們來簡要聊一聊注冊和登入。注冊APP成功後,就可以登入。看似簡單的操作,其實蘊含了很多密碼安全的問題。

注冊登入原理及密碼安全問題

     當你注冊APP,填寫使用者名和密碼,點選送出後, APP背景肯定需要“存儲你的使用者名和密碼”,而當你輸入使用者名和密碼進行登入時,APP背景就能判定你輸入的使用者名和密碼與當時注冊的使用者名和密碼是否比對,進而确定是否讓你登入。

      那麼,有沒有思考過這個問題:APP背景開發的程式員GG們,能偷窺到你的密碼嗎?他們會盜用你的賬号和密碼進行登入嗎?黑客攻擊APP背景後,能盜用你的賬号和密碼嗎?

      顯然,這是不能允許的。沒有辦法在道德和法律的規範下嚴格禁止這樣的行為,那就要從技術機制上禁止,要確定即使在資料庫和程式代碼被盜走的情況下,壞人也無法破解密碼。

1.密碼直接明文存儲

       如果在APP背景資料庫中直接存儲使用者名和密碼,那麼黑客可就要在睡夢中笑醒了:

注冊登入原理及密碼安全問題

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

注冊登入原理及密碼安全問題

2.密碼加密存儲

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

注冊登入原理及密碼安全問題

      這種方式也挺業餘的,既然能加密,就有辦法解密,同樣存在密碼被盜的風險,如果APP背景能以某種方式還原密碼,那肯定就是流氓系統。我們也有這樣一個常識:當使用者忘記密碼後,正确做法不是APP背景告訴使用者密碼是多少(因為APP背景壓根就不應該知道使用者的密碼),而應該讓使用者重新設定密碼。

3.密碼直接哈希存儲

       哈希函數,單向散列,且幾乎不沖突,故可以考慮對密碼進行哈希變換後存儲,如下:

注冊登入原理及密碼安全問題

      如此一來,從理論上講,即使哈希值yyyyyy被盜走,别人也難以還原成原來的abcd123了,因為哈希函數不可逆。這樣貌似就實作了密碼的安全存儲,不過,有點太天真了。

     如果資料庫和程式代碼被盜,從理論上講,難以用yyyyyy反推出密碼abcd123, 但黑客可以用彩虹表攻擊,分分鐘就能破解出密碼abcd123,  彩虹表攻擊的圖示如下:

注冊登入原理及密碼安全問題

      簡單解釋一下:黑客通過長期積累,對一些常用的字元串進行哈希,得到哈希值,形成一張很大的資料表,一旦黑客盜走資料庫中的密碼哈希值yyyyyy, 就可以在資料表中進行查找,很快就能知道密碼是abcd123, 這個資料表,就是所謂的彩虹表。

      理論上不可反解的哈希函數,被狡猾的黑客給“破解”了,并且得到了密碼。

4.密碼多次哈希後存儲

      有的朋友可能覺得彩虹表能實作攻擊,主要是因為隻用一次哈希,那麼多加幾次哈希,是不是就解決問題了呢?

      顯然不是。多次哈希後,一旦黑客拿到你多次哈希的程式代碼和資料庫,便可以構造多重彩虹表,分分鐘破解密碼:

注冊登入原理及密碼安全問題

5.固定鹽值的哈希存儲(無需存鹽)

      思考一下,現在的問題是,要抗彩虹表攻擊,可以考慮這麼做:

P = hash(user + hash(password))       

       此處的user就是使用者名,用作鹽值。這樣,就增加了黑客的破解難度,因為黑客需要針對每個user做一張特定的二重彩虹表,才有可能破解。

       即便如此,在攻擊一些重要user時, 黑客可能感覺值得嘗試一下,是以,用固定鹽還是存在較大風險。  

6.随機鹽值的哈希存儲(需要存鹽)

       既然固定鹽值不好,那就用随機鹽吧,于是可以考慮這麼做:

P = hash(salt + hash(password))       

      這個随機鹽salt,需要存儲在APP背景資料庫中。可問題是,APP和APP背景需要使用相同的随機鹽,那麼APP是怎樣擷取APP背景的随機鹽呢?這又涉及到一系列的加密算法(RSA和AES)和秘鑰管理問題,在實際系統中,有些公司就是這麼做的。

      随機鹽的引入,可以讓彩虹表失效,黑客隻能“望鹽興歎”。

7.bcrypt存儲(無需存鹽)

      有沒有更簡潔且安全的做法呢?有的,用bcrypt吧。我始終覺得,bcrypt這個名字不太好,應該叫bSHA, 其實也不用糾結名字。bcrypt是一個帶随機鹽的哈希函數,在哈希值中,又攜帶了鹽的資訊,是以,在APP背景,就能從哈希值中解析出APP端使用的随機鹽,是以,該随機鹽不需要被APP背景資料庫存儲。使用bcrypt後,注冊登入邏輯圖如下:

注冊登入原理及密碼安全問題

       而且,bcrypt是一個相對較慢的哈希函數(比如設定1s),這就大大增加了黑客暴力破解的難度。這裡要說明的是,APP端的bcrypt慢,但APP背景對應校驗函數并不慢,是以不會影響APP背景服務的性能。

掃碼登入原理 

      實際上,使用者在APP上登入後,會擷取一個登入态票據(session key, 一般簡寫為skey),在後續的每次操作中,使用者不必再輸入密碼了,APP自動攜帶登入态票據,此時APP背景進行登入态票據校驗就可以了,也提升了便利性和安全性。

      使用者登入APP後,擷取到了登入态票據skey,  然後使用者利用APP對網頁上的二維碼進行掃描,擷取隐藏在二維碼中的token, 并送出到背景,實作掃碼登入,掃碼登入的邏輯圖如下:

注冊登入原理及密碼安全問題

      這個圖一目了然,不需要具體解釋每一步。值得注意的是,步驟6執行完後,步驟3中的輪詢才會知道網頁token和APP端的userID/skey在背景建立了關聯,此時網頁的掃碼登入也就成功了。

繼續閱讀