Android中新引進(jìn)的Google Authenticator驗(yàn)證系統(tǒng)工作原理淺析
為了改進(jìn)Android的安全問題,Google在Android系統(tǒng)中引入了谷歌驗(yàn)證應(yīng)用(Google Authenticator)來保證賬號(hào)的安全。谷歌驗(yàn)證應(yīng)用的使用方法是:用戶安裝手機(jī)客戶端,生成臨時(shí)身份驗(yàn)證碼,提交到服務(wù)器驗(yàn)證身份,類似的驗(yàn)證系統(tǒng)還有Authy。Robbie在其GitHub頁面發(fā)布了自己用Go語言實(shí)現(xiàn)的版本,并撰寫了一篇博文來解釋其工作原理。
通常來講,身份驗(yàn)證系統(tǒng)都實(shí)現(xiàn)了基于時(shí)間的一次性密碼算法,即著名的TOTP(Time-Based One-Time Password)。該算法由三部分組成:
1.一個(gè)共享密鑰(一系列二進(jìn)制數(shù)據(jù))
2.一個(gè)基于當(dāng)前時(shí)間的輸入
3.一個(gè)簽名函數(shù)
1、 共享密鑰
用戶在創(chuàng)建手機(jī)端身份驗(yàn)證系統(tǒng)時(shí)需要獲取共享密鑰。獲取的方式包括用識(shí)別程序掃描給定二維碼或者直接手動(dòng)輸入。密鑰是三十二位加密,至于為什么不是六十四位,可以參考維基百科給出的解釋。
對(duì)于那些手動(dòng)輸入的用戶,谷歌身份驗(yàn)證系統(tǒng)給出的共享密鑰有如下的格式:
xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
256位數(shù)據(jù),當(dāng)然別的驗(yàn)證系統(tǒng)可能會(huì)更短。
而對(duì)于掃描的用戶,QR識(shí)別以后是類似下面的URL鏈接:
otpauth://totp/Google%3Ayourname@gmail.com?secret=xxxx&issuer=Google
2、 基于當(dāng)前時(shí)間的輸入
這個(gè)輸入是基于用戶手機(jī)時(shí)間產(chǎn)生的,一旦用戶完成第一步的密鑰共享,就和身份驗(yàn)證服務(wù)器沒有關(guān)系了。但是這里比較重要的是用戶手機(jī)時(shí)間要準(zhǔn)確,因?yàn)閺乃惴ㄔ韥碇v,身份驗(yàn)證服務(wù)器會(huì)基于同樣的時(shí)間來重復(fù)進(jìn)行用戶手機(jī)的運(yùn)算。進(jìn)一步來說,服務(wù)器會(huì)計(jì)算當(dāng)前時(shí)間前后幾分鐘內(nèi)的令牌,跟用戶提交的令牌比較。所以如果時(shí)間上相差太多,身份驗(yàn)證過程就會(huì)失敗。
3、 簽名函數(shù)
谷歌的簽名函數(shù)使用了HMAC-SHA1。HMAC即基于哈希的消息驗(yàn)證碼,提供了一種算法,可以用比較安全的單向哈希函數(shù)(如SHA1)來產(chǎn)生簽名。這就是驗(yàn)證算法的原理所在:只有共享密鑰擁有者和服務(wù)器才能夠根據(jù)同樣的輸入(基于時(shí)間的)得到同樣的輸出簽名。偽代碼如下:
hmac = SHA1(secret + SHA1(secret + input))
本文開頭提到的TOTP和HMAC原理類似,只是TOTP強(qiáng)調(diào)輸入一定是當(dāng)前時(shí)間相關(guān)。類似的還有HOTP,采用增量式計(jì)數(shù)器的方式,需要不斷和服務(wù)器同步。
算法流程簡介
首先需要用base32解碼密鑰,為了更方便用戶輸入,谷歌采用了空格和小寫的方式表示密鑰。但是base32不能有空格而且必須大寫,處理偽代碼如下:
original_secret = xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
secret = BASE32_DECODE(TO_UPPERCASE(REMOVE_SPACES(original_secret)))
接下來要從當(dāng)前時(shí)間獲得輸入,通常采用Unix時(shí)間,即當(dāng)前周期開始到現(xiàn)在的秒數(shù)
input = CURRENT_UNIX_TIME()
這里有一點(diǎn)需要說明,驗(yàn)證碼有一個(gè)時(shí)效,大概是30秒。這種設(shè)計(jì)是出于方便用戶輸入的考慮,每秒鐘變化的驗(yàn)證碼很難讓用戶迅速準(zhǔn)確輸入。為了實(shí)現(xiàn)這種時(shí)效性,可以通過整除30的方式來實(shí)現(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))
完成這些代碼,基本就已經(jīng)實(shí)現(xiàn)了兩次驗(yàn)證的功能。由于HMAC是個(gè)標(biāo)準(zhǔn)長度的SHA1數(shù)值,有四十個(gè)字符的長度,用戶很難一次性正確輸入,因此還需要做一些格式上的處理??蓞⒖枷旅娴膫未a:
four_bytes = hmac[LAST_BYTE(hmac):LAST_BYTE(hmac) + 4]
large_integer = INT(four_bytes)
small_integer = large_integer % 1,000,000
相關(guān)文章
Android自定義超級(jí)炫酷的ViewPage指示器
由于應(yīng)公司開發(fā)要求,有一個(gè)顏色漸變帶縮放的指示器,雖然網(wǎng)上很多大佬開源的指示器開源庫,但如果一直都是使用別人造的輪子,那么對(duì)于自身的能力是毫無提升作用的,即使是參考別人的,然后自己動(dòng)手寫一遍那對(duì)于自身來說也是一種升華2022-07-07
Android實(shí)現(xiàn)微信側(cè)滑關(guān)閉頁面效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)微信側(cè)滑關(guān)閉頁面效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android實(shí)現(xiàn)退出界面彈出提示對(duì)話框
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)退出界面彈出提示對(duì)話框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
android的ListView點(diǎn)擊item使item展開的做法的實(shí)現(xiàn)代碼
這篇文章主要介紹了android的ListView點(diǎn)擊item使item展開的做法的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12
Android實(shí)戰(zhàn)打飛機(jī)游戲之菜單頁面設(shè)計(jì)(1)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)戰(zhàn)打飛機(jī)游戲之菜單頁面設(shè)計(jì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
Android Studio打包.so庫到apk中實(shí)例詳解
這篇文章主要介紹了Android Studio打包.so庫到apk中實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04
跨平臺(tái)移動(dòng)WEB應(yīng)用開發(fā)框架iMAG入門教程
這篇文章主要介紹了跨平臺(tái)移動(dòng)WEB應(yīng)用開發(fā)框架iMAG入門教程,iMAG最大的特點(diǎn)是生成各移動(dòng)平臺(tái)的原生代碼,需要的朋友可以參考下2014-07-07
Activity isFinishing()判斷Activity的狀態(tài)實(shí)例
下面小編就為大家分享一篇Activity isFinishing()判斷Activity的狀態(tài)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03

