みなさん突然ですが、連番は好きですか?
車のナンバープレートや切符の端の番号など本来はランダムであるはずの番号が連番になっているとちょっとだけ幸せになることが多いと思います。
多くの人が他要素認証(MFA)のために使っている6桁の数字も多くの場合はランダムです。
私は今まで6桁のうち4桁が揃ったところまでは見たことがありますが、それ以上は見たことがありません。
毎日のようにMFAトークンを入力しているのに4桁がやっとということは、もしかしたら一生MFAトークンの連番を見ることができずに死んでしまうかもしれません。
それでは死んでも死にきれないので、なんとかして連番をMFAアプリに表示させたいと思います。
MFAトークンの仕様
多くのMFAで使用されている、30秒毎に6桁の数字が変わるMFAトークンはTOTPというアルゴリズムによって生成されています。
TOTPはRFC6238によって策定されているワンタイムパスワード生成のためのアルゴリズムです。
より詳しい説明や実装例は以下の記事を参考にすると良いでしょう。
強引に計算してみる
上で紹介したブログ記事にあるようにTOTPの計算にはSHA1関数が使われています。
この関数は暗号学的ハッシュ関数であり、逆関数を求めることが非常に困難であることが分かっているので、総当たり的に計算してみます。
TOTPの計算のための便利なライブラリがRubyにはあるので、それを利用します。
https://github.com/mdp/rotp
gem install rotp base32
require 'time'
require 'base32'
require 'rotp'
target_time = Time.parse("目的の日時")
target_number = "777777"
random = Random.new
secret = nil
loop do
bytes = random.bytes(10)
secret = Base32.encode(bytes)
totp = ROTP::TOTP.new(secret)
break if totp.at(target_time) == target_number
end
p secret
やっていることはとてもシンプルで、目的の日時のワンタイムパスが目的の値になるまでひたすら乱数を生成しているだけです。
お使いのPCの性能にもよりますが、数十秒〜数分で好きなタイミングで好きな数字を表示させるためのシークレットが求まります。
あとはここで求まったシークレットを以下のページなどのTOTP用のQRコード生成ツールに入力すればOKです。
https://rootprojects.org/authenticator/
そのあとは指定した時刻にMFAアプリの画面を開けばOKです。
これでちょっとだけ幸せな気分になることができました。
幸せのおすそ分けとして、明日の00:00:00に777777になるQRコードを貼り付けておきます。
日付が変わる瞬間にちょっとだけの幸せが訪れますように。