Github于2023-03-09推出一項提高軟件安全標準的措施,所有在Github上貢獻過代碼的開發人員在年底前必須完成 2FA(Two-factory authentication,雙因子認證)。初聽此事之時,不以為意,因為自己之前就知道雙因子認證,就是說登錄賬號時,不僅需要密碼,還需要額外的認證方式,我們熟知的短信驗證碼就是其中的一種方式。
2FA
但當我準備啟用Github賬號的2FA時,我卻發現Github雖然提供了SMS/Text message的選項,但并不支持國內手機號碼,也就是說大陸無法收到驗證碼。Github支持的二次驗證方式如下
- Authenticator app
- SMS/Text message
- Security keys
- Github Mobile
移動端的Github應用也可以用來做二次驗證,但是為了安全,我的手機通常沒有搭載科學上網的軟件,此項也被PASS。這時只能使用Authenticator app的方式,采用了 OTP(One Time Password,一次性密碼) 算法。
介紹完2FA場景,我們就知道OTP原理就是,用戶在首次登錄或者注冊時,云端不僅保存用戶的密碼,還會生成一個密鑰,服務器通常使用二維碼的方式呈現給用戶,這個密鑰需要用戶使用客戶端保存,也就是需要支持OPT的程序去掃描二維碼。這樣云側端側擁有了同樣的密鑰,就可以基于相同的算法生成相同的一次性密碼。通常這個算法就是TOTP(Time-based One-time Password,基于時間戳的一次性密碼)。
TOTP
TOTP定義在 RFC 6238,附錄給出了JAVA實現TOTP的代碼,讀者可以自取。其實現算法如下
TOTP=HMAC-SHA-1(K, (T - T0)/X)
TOTP基于具有時間戳計數器的OTP(一次性密碼),其中K為共享密鑰,T為當前時間戳,T0為開始的時間戳,X為時間步長。
- 密鑰生成:在為帳戶設置TOTP時,將生成一個唯一的密鑰。該密鑰在用戶設備和認證服務器之間共享。
- 時間同步:用戶設備和認證服務器需要同步到相同的時間源。TOTP算法依賴于當前時間來生成一次性密碼。
- OTP生成:TOTP算法將密鑰和當前時間結合起來,應用Hash函數生成一次性密碼。此密碼通常包含6-8位數字,并具有有限的有效期,例如30或60秒。
- OTP驗證:當用戶嘗試登錄時,輸入常規密碼以及由TOTP應用程序或設備生成的一次性密碼。然后,認證服務器根據共享密鑰和當前時間獨立生成預期的OTP。如果用戶輸入的OTP與服務器生成的OTP匹配,則授權訪問。
2FA/OTP客戶端
Github推薦的都是付費客戶端,例如authy,如果你是土豪,請隨意。很顯然本人不是,所以花費了一些時間收集一些比較好用的工具,包括瀏覽器插件、APP以及桌面客戶端,很多密碼管理器都有計算OTP驗證碼的功能,在使用的同時,我們也要考慮安全性。
- 神鎖離線版,十年前的國內一家創業公司,轉型期間的作品,我看了一些他們開發的技術博客,還是很懂安全和客戶隱私的,并且隱私聲明中聲稱未收集任何個人數據。
- 微信小程序Authly,安全性未知,好處是可以綁定微信賬號,管理多個密碼。
- 身份驗證器-Chrome插件,離線運行,想在多個設備上登錄Github,可能就犯難了。
- Microsoft Authenticator,微軟官方出品的身份驗證器,可賬號同步,如果你相信大廠的實力和安全性,不二之選,缺點是過于臃腫(278.89MB)。
- Google Authenticator,谷歌官方出品的身份驗證器,可賬號同步,相比于微軟,沒有科學上網的話,不建議使用Google的產品。
總結
客戶端在離線情況下,仍然可以生成與服務器一致的一次性密碼,這是由于他們最初都約定好了一個共享密鑰,由此密鑰+時間戳經過相同的算法計算而來。一次性密碼是雙因子驗證的有力補充,當然一次性密碼也可以用在其他領域,不僅僅是2FA。例如針對智能門鎖,我們可以利用TOTP生成臨時密碼,給清潔工自行開門;工商銀行網銀的動態令牌生成器在離線場景下仍然可以生成動態密碼。