LoginSignup
4
5

More than 5 years have passed since last update.

Perlでワンタイムパスワード認証を導入するために使えそうなライブラリ

Posted at

Perlでワンタイムパスワード認証を導入するために使えそうなライブラリ

概要

最近流行の不正ログインへの対策なんかで、ワンタイムパスワード(以下OTP)の導入がはやっている。
ユーザーがとても使いにくい点など、OTP認証についての議論はおいておいて、既存の認証のしくみに加えOTP認証を実装しようと思ったらどんな感じになるかを考え、実現するために必要そうなライブラリを用意した話。

ここでいうOTP関連の仕様

もう一個関係ありそうなのがあるがこれは今回の話の対象外。

OTPの使いどころ

例えば、このように使われているのを見かけることがある。

  1. 通常のパスワード認証 + OTP入力 : Googleなど
  2. ユーザーが設定したPIN + OTPによる認証 : ハードウェアトークンを用いるSSL-VPN系のプロダクトとか
  3. 10個の(一見ランダムな)数字を保存しておいて一回ずつ利用 : Googleのバックアップコードみたいなやつ

ここではこれらの方式が素晴らしく、導入すべきだという話ではない。
3つめはいくらでも簡単に実装できるので微妙だが、HOTP/TOTPの利用という観点からこれらの処理を細かく見ていく。

パスワード認証 + OTP認証

  • Google Authenticator的なものにOTPの設定をする
    • OTP設定作成(TOTP)、DBなどに保存
    • 設定用URIを生成
    • QRコードなどで読み込ませる
  • パスワード認証成功後、OTP入力を求め、入力されたOTPを検証
    • ユーザーに紐づくOTP設定をDBなどから読み込み
    • OTPの値を計算して比較

PIN + OTP認証

  • Google Authenticator的なものにOTPの設定をする
    • OTP設定作成(TOTP)、DBなどに保存
    • 設定用URIを生成
    • QRコードなどで読み込ませる
  • PIN + OTP入力を求め、入力されたOTPを検証
    • ユーザーに紐づくOTP設定をDBなどから読み込み
    • OTPの値を検証

PIN + OTPの値は生で送っていいのか...とかは今回割愛する。
結局パスワードがPINになって一緒に送られるかどうかの話。

10個の(一見ランダムな)数字を保存しておいて一回ずつ利用

  • 数字の払い出し
    • OTP設定作成(HOTP)、DBなどに保存
    • カウンタに用いる値を10個作成(連番でもランダムでも良い)、DBなどに保存
    • それぞれのOTPの値を払い出す
  • OTPを受け取って検証
    • ユーザーに紐づくOTP設定をDBなどから読み込み
    • カウンタに用いる値(で有効なもの)をDBなどから読み込み
    • それぞれの値でOTPを生成し、それに含まれていたらそのカウンタの値を削除

必要な機能

Google Authenticattorへの設定用URLは仕様が公開されているのでそれにしたがって作成すれば良い。
KeyUriFormat - google-authenticator

OTPの値の計算については、Authen::OATH が使える。

あとはOTP設定の作成/保存と読み込みあたりを簡単にするしくみがあれば捗りそう。
データストア/既存のユーザーとの紐付けの部分はサービス独自なものであるので、後述するような"薄い"内部用HTTPサーバーのためのライブラリを検討した。

作ったもの

Authen::OATH::KeyURI

Authen::OATH::KeyURI

Google AuthenticatorにHOTP/TOTPの設定を行うときに読み込ませるURIを生成するモジュール。

生成したURIをリンク/QRコードなどで読み込ませることで設定が可能。

Net::OATH::Server

Net::OATH::Server

(今のところは)InternalなOTP認証用HTTP Serverのための"薄い"PSGIアプリケーションを提供しているモジュール。

  • このモジュールがやること
    • OTP設定のCRUD処理の"インターフェース"の提供
    • OTP設定のCRUD処理とOTPの検証(Login)処理のPSGIアプリケーションを提供
  • 利用者がやること
    • インターフェースに従ってOTP設定のCRUD処理を"実装"
    • 提供されているPSGIアプリケーションを内部向けHTTP Serverとして動かす
    • Create機能で取得したOTP設定のidをユーザーに紐付け
    • Create機能で取得したOTP設定とAuthen::OATH::KeyURIからユーザー設定用URLを生成
    • OTP検証時にLogin機能を利用
    • 不要になったらDelete
    • 細かいパラメータを利用する場合はUpdate

OTP設定処理

OTP認証処理

これらを使うと、内部向けにHTTP Serverを立てて利用することでOTP認証を簡単に実装できそう。

さすがにわざわざHTTP Serverたてるのもあれだなって言われそうなので、OTP設定のCRUD/Login部分をPSGIアプリケーションと切り離して、モジュールにして密結合な利用もできるようにする予定。

ちなみに、これをプロダクション環境で使う予定とかは今のところない。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5