会社行きたくなかったんです。

自由になりたくて会社辞めました

VB.net プログラミング

VB.netで二段階認証のコードを生成するツールを作りました。

投稿日:

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段階認証のコードを求められる現象が改善されてしまいました。

-VB.net, プログラミング

Copyright© 自由になりたくて会社辞めました , 2024 AllRights Reserved Powered by AFFINGER4.