2段階認証のアプリが入っているスマホが壊れたらどうなる?という記事を書いた時に、アマゾンなどの二段階認証に設定をやり直したのですが、その後、一時期、毎回コード入力画面が出るようになってしまいました。
Google Chromeで2段階認証のコード入力が毎回出てしまう場合の対処法
で、Chromeの問題は解消しました。
VB.netのWEB BrowserコントロールはInternet Explorerを使っています。
WEB Browserコントロールを使用して、アマゾンのセラーセントラルに自動ログインするプログラムが、毎回、コード入力を求められるようになってしまいました。
そのため、自動ログインツールが自動的にコードを計算してサインインできるようにしたいと考えました。
スポンサーリンク
二段階認証はタイムシンクロナス方式(時刻同期方式)「Time-basedOne-Time Password」の頭文字をとって「TOTP方式」という仕組みでコードの生成を行っているようです。
時刻とキーから計算した数字を使っているだけらしいのです。
AWSで二段階認証を設定した時に生成されるQRコードを以下のフォーマットになっています。
otpauth://totp/Amazon%20Web%20Services:[ユーザー情報]?secret=[キー]&issuer=Amazon%20Web%20Services
[キー]と現在の時刻から計算した結果が、Authenticatorアプリと一致すれば良いということがわかります。
TOTPの計算方法
まずは、現在の時刻をUnixTimeに変換します。
UnixTimeとは、1970年1月1日からの経過秒数で表される日付の形式です。
UnixTimeは、毎秒変わってしまいます。
そのため、UnixTimeをTimeStepで割った値を求めます。
TimeStepは通常30です。
30秒間は同じコードが有効だということです。
UnixTimeをTimeStepで割った値をタイムコードと呼んだりするようです。
secretはBase32でエンコーディングされています。
以下、VB.netのコードです。
「Base32Decode」という関数は別記事(VB.netでBase32をデコードするコード書きました。)で作ったものを使っています。
'現在の時刻をUnixTimeに変換
Dim iUnixTime As Integer
iUnixTime = (DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds
'UnixTimeをTimeStepで割った値
'小数点以下を切り捨てています。
'btCounterを8バイトにしたいので、この値はLongにしておきます。
Dim lCounter As Long
lCounter = Math.Floor(iUnixTime / 30)
Dim hmac As Security.Cryptography.HMACSHA1
Dim hs As Byte()
Dim btCounter As Byte()
Dim btSecret As Byte()
'iCounterをバイト配列に変換します。
btCounter = BitConverter.GetBytes(lCounter)
'BitConverterはリトルエンディアンを返すので、
'ビッグエンディアンに変換しています。
btCounter = btCounter.Reverse().ToArray()
'2段階認証のsecretをバイト配列に変換します。
btSecret = Base32Decode([2段階認証のsecret])
'SHA1のハッシュ値を計算しています。
hmac = New Security.Cryptography.HMACSHA1(btSecret)
hs = hmac.ComputeHash(btCounter)
'コードを計算しています。
Dim iOffset As Integer
iOffset = hs(19) And &HF
Dim iCode As Integer
iCode = (hs(iOffset) And &H7F) << 24 _
Or (hs(iOffset + 1) And &HFF) << 16 _
Or (hs(iOffset + 2) And &HFF) << 8 _
Or hs(iOffset + 3) And &HFF
'右から6桁取得しています。(たいてい6桁です。)
'これが取得したかったコードです。
Dim sCode As String
sCode = CStr(iCode).Substring(CStr(iCode).Length - 6, 6)
スマホにインストールしてあるMicrosoft Authenticatorアプリと同じ数字がでるようになりました。
このコード書いているうちに、WEB Browserコントロールで毎回2段階認証のコードを求められる現象が改善されてしまいました。