是不是除了手機上的應用程式,我們可以自行做一個 Google Authenticator 出來?
答案是可以的,而且並不這麼困難。
程式碼可以在很多地方找得到,比如維基百科,以及其中參照的各種程式語言。
主要闡述其中的步驟,因為有些可能發生錯誤的地方:
ㄧ、取得 16 碼密鑰:在開啟 2FA (Two-Factor Authenticator) 兩階段驗證的功能時,一般出現提供掃描的 QR code,這時選取手動輸入,會獲得使用 base32 編碼的 16 碼密鑰。
二、將 16 碼密鑰轉換成二進位碼:轉換完成之後,其長度應該為 10 bytes,或者 80 bits;如果不足的話,需要在最高位元補滿二進位 0。假設這時取得的是 $k。
三、基於時間戳記的訊息碼:所使用的時間戳記是 Unix 時間,並且依據設定為每 30 秒變換一次,所以在擷取 Unix 時間之後,除以 30 並且無條件捨去,就是稍後會用到的訊息碼。長度是 8 bytes,或者 64 bits;不足的話在最高位元補滿二進位 0。假設取得的訊息碼為 $m。
四、計算 HMAC 雜湊碼:以 SHA-1 (Secure Hash Algorithm 1) 架構,使用上述的密鑰 $k 以及訊息 $m,透過 HMAC (Hash-based message authentication code) 計算加密後的雜湊碼。長度是 20 bytes,或者 160 bits。不足的話一樣在最高位元補滿二進位 0。假設獲得雜湊碼 $h。
五、偏移量:最終的授權碼並不是來自於整段雜湊碼,而是依據偏移量來選取其中的一小段。偏移量來自雜湊碼 $h 的最低 4 個位元 (bit),由此可知其範圍介於 0 到 15 之間。
六、擷取原始授權碼:從雜湊碼 $h 中,以最高位元組 (byte) 為位置 0 起算,從偏移量的位置開始,擷取 4 個位元組 (byte),並且將最高位元 (bit) 設為二進位 0,獲得 $th。
七、最終授權碼:將 $th 轉換為十進位數字,並且取 1000000 的餘數,不足 6 位數則在左邊補上 0,就得到 6 位數的最終授權碼了。