2017年11月2日 星期四

以C#實作Google Authenticator 產生一次性驗證碼

以C#實作Google Authenticator 產生一次性驗證碼

之前寫了自動登入到合作夥伴公司的B2B平台網站抓取每日報表,
該平台原本是透過圖形驗證碼的方式來阻擋爬蟲,但其選擇圖形其實是很單純,
難易度太低,有心人要解開其實是很簡單的,
後來該平台應該有意識到這個問題,最近更新為使用Google Authenticator的一次性密碼驗證碼TOPT ( Time-based One-time Password ) 進行二階段驗證

1.先下載Google Authenticator app:Android, iOS

2.使用該 app 掃瞄讀取B2B平台所提供的QRCode後便會新增一個自動產生一次性驗證碼的項目,驗證碼每30秒就會變動一次



不得不說這的確是增強了網站登入的防護,要給予掌聲鼓勵!

但這種方式對良善之心要運用自動登入的老百姓該怎麼辦?
難道要回到原始時代人工作業嗎?

想來想去,心有不甘!
走~!想解決方案去!!!

解決方案一:

即然我們可以看到這個驗證碼,那只要在VM 虛擬機器上掛個Android系統
再安裝Google Authenticator 來產生驗登碼,
寫個程式自動擷取該視窗驗證碼的畫面後進行OCR辦識,這樣就解決了。
這是我一開始的想法,後來也實作出來了(擷取視窗驗證碼的方式之後再寫另一篇)。

這樣的缺點是:
1.擷取畫面時如果該視窗突然被其他視窗蓋到就會失敗
2.須安裝VM,而且要一直開著…有點浪費系統資源

有沒有方式可以解決浪費資源這點呢?後來想說會不會Chrome有相關外掛呢?
這樣就能在要執行時再開啟Browser進行截取就好了
google了一下還真有耶!

但這個網站外掛並不是google所開發的,為什麼他產生的也可以適用?
這代表演算法一定是有公開
(Google Authenticator 也是程式碼開源的,有興趣可以到GitHub Google Authenticator參考 )
所以接下來就生出了更好的解決方案了:

解決方案二:

直接實作演算法(我是參考Tin Isles的javascript實作改用c#東抄西抄來實現而已...
只要有了金鑰,透過演算法就可以得出一次性碼囉~
那金鑰哪來?其實上面所說的QRCode只是一個紀錄私密金鑰的載體而已:



程式碼參考如下:

參考資料: