密碼是最常見的認證方法,但是不安全,容易洩露和冒充。
越來越多的地方,要求啟用雙因素認證(Two-factor authentication,簡稱 2FA)。本文介紹它的概念和實現方法。
文章結尾有一則活動訊息,優達學城(Udacity)的"雙十一優惠",課程最高減免1111元。
一、雙因素認證的概念
一般來說,三種不同型別的證據,可以證明一個人的身份。
- 秘密資訊:只有該使用者知道、其他人不知道的某種資訊,比如密碼。
- 個人物品:該使用者的私人物品,比如身份證、鑰匙。
- 生理特徵:該使用者的遺傳特徵,比如指紋、相貌、虹膜等等。
這些證據就稱為三種"因素"(factor)。因素越多,證明力就越強,身份就越可靠。
雙因素認證就是指,透過認證同時需要兩個因素的證據。
銀行卡就是最常見的雙因素認證。使用者必須同時提供銀行卡和密碼,才能取到現金。
二、雙因素認證方案
常用的雙因素組合是密碼 + 某種個人物品,比如網上銀行的 U 盾。使用者插上 U 盾,再輸入密碼,才能登入網上銀行。
但是,使用者不可能隨時攜帶 U 盾,手機才是最好的替代品。密碼 + 手機就成了最佳的雙因素認證方案。
國內的很多網站要求,使用者輸入密碼時,還要提供短訊息傳送的驗證碼,以證明使用者確實擁有該手機。
但是,短訊息是不安全的,容易被攔截和偽造,SIM 卡也可以克隆。已經有案例,先偽造身份證,再申請一模一樣的手機號碼,把錢轉走。
因此,安全的雙因素認證不是密碼 + 短訊息,而是下面要介紹的 TOTP。
三、TOTP 的概念
TOTP 的全稱是"基於時間的一次性密碼"(Time-based One-time Password)。它是公認的可靠解決方案,已經寫入國際標準 RFC6238。
它的步驟如下。
第一步,使用者開啟雙因素認證後,伺服器生成一個金鑰。
第二步:伺服器提示使用者掃描二維碼(或者使用其他方式),把金鑰儲存到使用者的手機。也就是說,伺服器和使用者的手機,現在都有了同一把金鑰。
注意,金鑰必須跟手機繫結。一旦使用者更換手機,就必須生成全新的金鑰。
第三步,使用者登入時,手機客戶端使用這個金鑰和當前時間戳,生成一個雜湊,有效期預設為30秒。使用者在有效期內,把這個雜湊提交給伺服器。
第四步,伺服器也使用金鑰和當前時間戳,生成一個雜湊,跟使用者提交的雜湊比對。只要兩者不一致,就拒絕登入。
五、TOTP 的演算法
仔細看上面的步驟,你可能會有一個問題:手機客戶端和伺服器,如何保證30秒期間都得到同一個雜湊呢?
答案就是下面的公式。
TC = floor((unixtime(now) − unixtime(T0)) / TS)
上面的公式中,TC 表示一個時間計數器,unixtime(now)
是當前 Unix 時間戳,unixtime(T0)
是約定的起始時間點的時間戳,預設是0
,也就是1970年1月1日。TS 則是雜湊有效期的時間長度,預設是30秒。因此,上面的公式就變成下面的形式。
TC = floor(unixtime(now) / 30)
所以,只要在 30 秒以內,TC 的值都是一樣的。前提是伺服器和手機的時間必須同步。
接下來,就可以算出雜湊了。
TOTP = HASH(SecretKey, TC)
上面程式碼中,HASH
就是約定的雜湊函式,預設是 SHA-1。
TOTP 有硬體生成器和軟體生成器之分,都是採用上面的演算法。
(說明:TOTP 硬體生成器)
(說明:Google Authenticator 是一個生成 TOTP 的手機 App)
五、TOTP 的實現
TOTP 很容易寫,各個語言都有實現。下面我用 JavaScript 實現2fa
來演示一下真實程式碼。
首先,安裝這個模組。
$ npm install --save 2fa
然後,生成一個32位字元的金鑰。
var tfa = require('2fa'); tfa.generateKey(32, function(err, key) { console.log(key); }); // b5jjo0cz87d66mhwa9azplhxiao18zlx
現在就可以生成雜湊了。
var tc = Math.floor(Date.now() / 1000 / 30); var totp = tfa.generateCode(key, tc); console.log(totp); // 683464
六、總結
雙因素認證的優點在於,比單純的密碼登入安全得多。就算密碼洩露,只要手機還在,賬戶就是安全的。各種密碼破解方法,都對雙因素認證無效。
缺點在於,登入多了一步,費時且麻煩,使用者會感到不耐煩。而且,它也不意味著賬戶的絕對安全,入侵者依然可以透過盜取 cookie 或 token,劫持整個對話(session)。
雙因素認證還有一個最大的問題,那就是帳戶的恢復。
一旦忘記密碼或者遺失手機,想要恢復登入,勢必就要繞過雙因素認證,這就形成了一個安全漏洞。除非準備兩套雙因素認證,一套用來登入,另一套用來恢復賬戶。
七、參考連結
- Multi-factor authentication, by Wikipedia
- Time-based One-time Password Algorithm, by Wikipedia
- Enabling Two-Factor Authentication For Your Web Application, by Bozhidar Bozhanov
- simontabor/2fa, by Simon Tabor
(正文完)
====================================
從業兩三年後,程式設計師往往遇到職業瓶頸,80%的人都把時間耗費在熬夜加班、修 Bug,只有少數人選擇業餘時間精進技術,提升自己的潛力,突破薪資天花板。
優達學城(Udacity)作為來自矽谷的前沿技術學習平臺,幫你掌握前沿技術。
它的課程和專案,來自Google、Facebook等矽谷名企,並提供人工審閱、一對一線上答疑等服務,拒絕浪費時間走彎路。
今年雙十一,與其囤積一年都用不完的便宜貨,不如來優達學城投資未來提升自我。11月1日~11月11日,課程全場最高減¥1111,讓你輕鬆享有矽谷學習資源!
優惠席位有限,先到先得,點選這裡瞭解詳情。
(完)