谷歌兩步驗證(Google authentiator)系統(tǒng)的工作原理和Golang實現(xiàn)

為了改進Android的安全問題蜂大,Google在Android系統(tǒng)中引入了谷歌驗證應用(Google Authenticator)來保證賬號的安全徘禁。谷歌驗證應用的使用方法是:用戶安裝手機客戶端勺拣,生成臨時身份驗證碼黔宛,提交到服務器驗證身份,類似的驗證系統(tǒng)還有Authy雳殊。Robbie在其GitHub頁面發(fā)布了自己用Go語言實現(xiàn)的版本哨颂,并撰寫了一篇博文來解釋其工作原理。

看過Robbie的代碼相种,你會發(fā)現(xiàn)他用到了系統(tǒng)的base32威恼,但是這里是有問題的,后文會說到

通常來講寝并,身份驗證系統(tǒng)都實現(xiàn)了基于時間的一次性密碼算法箫措,即著名的TOTP(Time-Based One-Time Password)。該算法由三部分組成:

  1. 一個共享密鑰(一系列二進制數(shù)據(jù))
  • 一個基于當前時間的輸入
  • 一個簽名函數(shù)

1. 共享密鑰

用戶在創(chuàng)建手機端身份驗證系統(tǒng)時需要獲取共享密鑰衬潦。獲取的方式包括用識別程序掃描給定二維碼或者直接手動輸入斤蔓。密鑰是三十二位加密,至于為什么不是六十四位镀岛,可以參考維基百科給出的解釋弦牡。

對于那些手動輸入的用戶,谷歌身份驗證系統(tǒng)給出的共享密鑰有如下的格式:

xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

256位數(shù)據(jù)漂羊,當然別的驗證系統(tǒng)可能會更短驾锰。

而對于掃描的用戶,QR識別以后是類似下面的URL鏈接:

otpauth://totp/xxx@xxx.com?secret=xxxx&issuer=Google

2. 基于當前時間的輸入

這個輸入是基于用戶手機時間產生的走越,一旦用戶完成第一步的密鑰共享椭豫,就和身份驗證服務器沒有關系了。但是這里比較重要的是用戶手機時間要準確,因為從算法原理來講赏酥,身份驗證服務器會基于同樣的時間來重復進行用戶手機的運算喳整。進一步來說,服務器會計算當前時間前后幾分鐘內的令牌裸扶,跟用戶提交的令牌比較框都。所以如果時間上相差太多,身份驗證過程就會失敗呵晨。

3. 簽名函數(shù)

谷歌的簽名函數(shù)使用了HMAC-SHA1瞬项。HMAC即基于哈希的消息驗證碼,提供了一種算法何荚,可以用比較安全的單向哈希函數(shù)(如SHA1)來產生簽名囱淋。這就是驗證算法的原理所在:只有共享密鑰擁有者和服務器才能夠根據(jù)同樣的輸入(基于時間的)得到同樣的輸出簽名。偽代碼如下:

hmac = SHA1(secret + SHA1(secret + input))

本文開頭提到的TOTP和HMAC原理類似餐塘,只是TOTP強調輸入一定是當前時間相關妥衣。類似的還有HOTP,采用增量式計數(shù)器的方式戒傻,需要不斷和服務器同步税手。

算法流程簡介

首先需要用base32解碼密鑰,為了更方便用戶輸入需纳,谷歌采用了空格和小寫的方式表示密鑰芦倒。但是base32不能有空格而且必須大寫,處理偽代碼如下:

original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))

golang中提供的 encoding/base32庫解碼出來的secret無論如何都不能得到跟Google Authenticator APP相同的結果不翩,最后發(fā)現(xiàn)兵扬,是golang的base32解碼出來的secret總是缺少位數(shù)】隍穑看了下源碼器钟,發(fā)現(xiàn)它的位數(shù)計算是:
func (enc *Encoding) DecodedLen(n int) int { return n / 8 * 5 }
這就意味著golang encoding/base32解碼出的位數(shù)總是5的整數(shù)倍,why妙蔗?要這么處理傲霸!

接下來要從當前時間獲得輸入,通常采用Unix時間眉反,即當前周期開始到現(xiàn)在的秒數(shù)

input = CURRENT_UNIX_TIME()

這里有一點需要說明昙啄,驗證碼有一個時效,大概是30秒寸五。這種設計是出于方便用戶輸入的考慮梳凛,每秒鐘變化的驗證碼很難讓用戶迅速準確輸入。為了實現(xiàn)這種時效性播歼,可以通過整除30的方式來實現(xiàn)伶跷,即:

input = CURRENT_UNIX_TIME() / 30

最后一步是簽名函數(shù)掰读,HMAC-SHA1秘狞,全部偽代碼如下:

original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
input = CURRENT_UNIX_TIME() / 30
hmac = SHA1(secret + SHA1(secret + input))

注意叭莫,SHA1中的input轉換為byte[8]的時候一定要是大端轉換

完成這些代碼,基本就已經實現(xiàn)了兩次驗證的功能烁试。由于HMAC是個標準長度的SHA1數(shù)值雇初,有四十個字符的長度,對于用戶來說太長减响,所以google會根據(jù)規(guī)則截取6位數(shù)字靖诗。可參考下面的偽代碼:

four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % power(10,6)

完整代碼可以參考我的golang實現(xiàn)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末支示,一起剝皮案震驚了整個濱河市刊橘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌颂鸿,老刑警劉巖促绵,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嘴纺,居然都是意外死亡败晴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門栽渴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尖坤,“玉大人,你說我怎么就攤上這事闲擦÷叮” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵墅冷,是天一觀的道長贮缕。 經常有香客問我,道長俺榆,這世上最難降的妖魔是什么感昼? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮罐脊,結果婚禮上定嗓,老公的妹妹穿的比我還像新娘。我一直安慰自己萍桌,他們只是感情好宵溅,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著上炎,像睡著了一般恃逻。 火紅的嫁衣襯著肌膚如雪雏搂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天寇损,我揣著相機與錄音凸郑,去河邊找鬼。 笑死矛市,一個胖子當著我的面吹牛芙沥,可吹牛的內容都是我干的。 我是一名探鬼主播浊吏,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼而昨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了找田?” 一聲冷哼從身側響起歌憨,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎墩衙,沒想到半個月后务嫡,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡底桂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年植袍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片籽懦。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡于个,死狀恐怖,靈堂內的尸體忽然破棺而出暮顺,到底是詐尸還是另有隱情厅篓,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布捶码,位于F島的核電站羽氮,受9級特大地震影響,放射性物質發(fā)生泄漏惫恼。R本人自食惡果不足惜档押,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祈纯。 院中可真熱鬧令宿,春花似錦、人聲如沸腕窥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽簇爆。三九已至癞松,卻和暖如春爽撒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背响蓉。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工硕勿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厕妖。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓首尼,卻偏偏與公主長得像挑庶,于是被迫代替她去往敵國和親言秸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理迎捺,服務發(fā)現(xiàn)举畸,斷路器,智...
    卡卡羅2017閱讀 134,639評論 18 139
  • 這篇文章主要講述在Mobile BI(移動商務智能)開發(fā)過程中凳枝,在網(wǎng)絡通信抄沮、數(shù)據(jù)存儲、登錄驗證這幾個方面涉及的加密...
    雨_樹閱讀 2,371評論 0 6
  • Guide to BluetoothSecurity原文 本出版物可免費從以下網(wǎng)址獲得:https://doi.o...
    公子小水閱讀 7,935評論 0 6
  • 1 基礎 1.1 對稱算法 描述:對稱加密是指加密過程和解密過程使用相同的密碼岖瑰。主要分:分組加密叛买、序列加密。 原理...
    御淺永夜閱讀 2,380評論 1 4
  • 朋友說蹋订,這個雙休日她過的極好率挣。換了床單,整理了衣服露戒,扔掉好多椒功。我問她扔掉的標準是什么,她說顏色焉了智什。我說我好像沒有...
    yoko52777閱讀 608評論 0 52