Nao000のぶろぐ

蝶を追っている少年になりたい

Elixirでワンタイムパスワード生成モジュール "one_time_pass_ecto" を試してみた

目次

  1. ワンタイムパスワードについて
  2. サンプル
  3. 参考サイト

ワンタイムパスワードについて

「ワンタイムパスワード」とはその名の通り、一定時間のみ有効なパスワードです。

ワンタイムパスワードのアルゴリズムは次の2種類があるようです。

  • HMAC-Based One-Time Password (HOTP)
  • Time-Based One-Time Password (TOTP)

今回試したのはTOTPです。

サンプル

リポジトリのREADMEを見ながら試せます⇒https://github.com/riverrun/one_time_pass_ecto

  1. モジュールをインストール
  2. 秘密鍵を生成
  3. ワンタイムパスワードを生成
  4. 認証してみる
  5. Google認証システムに追加してみる

モジュールをインストール

      {:one_time_pass_ecto, "~> 1.0"}

秘密鍵を生成

    iex(2)> secret = OneTimePassEcto.Base.gen_secret(32)

引数は秘密鍵の長さです。ドキュメントは 32 character (160-bit) を推奨していました。

ワンタイムパスワードを生成

秘密鍵を設定します。時間間隔も設定可能ですが初期値で30秒なので省略可能です。

    iex(4)> OneTimePassEcto.Base.gen_totp(secret)

認証してみる

    iex(8)> secret = OneTimePassEcto.Base.gen_secret(32)
    "F7UVBUVJNP66SOPC5GZJP67IBVIEXM7P"
    iex(9)> OneTimePassEcto.Base.gen_totp(secret)
    "442513"
    iex(10)> OneTimePassEcto.Base.check_totp("442513", secret)
    52685616
    iex(11)>

OneTimePassEcto.Base.check_totp("442513", secret)の実行結果のように適切なワンタイムパスワードを使えば何かの数値が返ってきます。リポジトリのソースを見ましたが、試行回数と時間間隔を使った計算結果のようですがよく分かりませんでした

30秒経過してから再度実行すると以下のようにfalseが返ってきます。

    iex(11)> OneTimePassEcto.Base.check_totp("442513", secret)
    false
    iex(12)>

Google認証システムに追加してみる

先程生成した秘密鍵を使ってGoogle認証システムに追加します。QRコードを生成して読み取る方法と手動入力どちらでも可能です。秘密鍵をネット上で入力するのは抵抗あるので手動入力しました。

QRコードを生成するのにこちらのサイトが便利そうです。 https://stefansundin.github.io/2fa-qr/

試してみると、Google認証システムに表示されるワンタイムパスワードとコマンドラインで生成するワンタイムパスワードが確かに同じなのが確認できます。感動です。

所感

AWSにログインする際にワンタイムパスワードを使っていますが、Elixirにそういったモジュールは無いのかな?と思って検索したらありました。なんでもある気がしてきました。

ワンタイムパスワードがOTPと表記されること、HOTP,TOTPがあること、RFCを覗いたときに少しだけ意味がわかったこと(RFCの内容の読み方が今まで全く分かりませんでした)、自分が生成したワンタイムパスワードをGoogle認証システムに追加できたことなど少しだけ世界が広がった気がしました。

参考サイト