13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

QRコードでシークレットを渡してワンタイムパスワード認証する(Google AuthenticatorとかAuthyみたいな)やつがやりたい

Last updated at Posted at 2022-01-29

自前のシステムでも多要素認証やりたい

画面に表示されたQRコードをスマホアプリにぴっと読み込み。
すると、30秒ごとにワンタイムパスワードが生成されるようになります。
あれを自前のシステムでもやりたいです。

QRコードの内容

QRコードの内容は otpauth:// で始まるURIになっています。
まずはこれを作れればスマホアプリで読み込めますね。

otpauth URI スキームの構造

こういうものの仕様は、RFCにあるかと思えば見つかりません。stackexchangeに質問がありました。回答によると、otpauth URIはBlackberryのソースコードに由来するようです。

URIの一般構造(引用元 RFC 3986)を眺めながらソースを追ってみます。

   foo://example.com:8042/over/there?name=ferret#nose
   \_/   \______________/\_________/ \_________/ \__/
    |           |            |            |        |
 scheme     authority       path        query   fragment

ソースによると otpauthtotp の2つのスキームと、普通のURLが使えます。

それぞれのスキームごとにURIの使い道をまとめてみます。

scheme authority path query fragment
otpauth totp ユーザ名 シークレット(secretキー) -
otpauth hotp ユーザ名 カウンター(counterキー)、シークレット(secretキー) -
totp ユーザ名 - - シークレット
上記以外 - - ユーザ名(userキー) シークレット

シークレットはBase32エンコードされた文字列です。

サンプルURI

こんなURIを作ればよさそうです。

otpauth://totp/anonymous@example.com?secret=NFWG65TFPFXXK===
otpauth://hotp/anonymous@example.com?counter=100&secret=NFWG65TFPFXXK===
totp://anonymous@example.com#NFWG65TFPFXXK===
http://example.com/?user=anonymous@example.com#NFWG65TFPFXXK===

QRコードにしてみました。

image.png

image.png

image.png

image.png

(QRコードは https://www.cman.jp/QRcode/qr_make/ で生成しました。感謝!)

読み込めますか?
Authyアプリでは、otpauthスキーマのtotpしか読み込めませんでした。

ここまでくれば

あとは、以下のことをすれば実装できそうです。

  • QRコード発行時
    • 暗号論的にランダムなシークレットを生成
    • シークレットを保管
  • ログイン時
    • Unix timeとシークレットからワンタイムパスワードを生成
    • ユーザが入力したワンタイムパスワードと、生成したワンタイムパスワードを比較して認証

気になること

シークレットを生のまま保管しておくのって、なんかパスワードを生のまま保管するみたいで気になります。

追記

さらに探したら、otpauth URIのフォーマットありました。

こんなフォーマットです。

otpauth://TYPE/LABEL?PARAMETERS

PARAMETERSには以下の項目があります。

パラメータ 必須? 既定値 説明
secret 必須 - シークレット
issuer 強く推奨 - シークレットの発行者
algorithm オプション SHA1 SHA1、SHA256、SHA512のいずれか
digits オプション 6 OTPの桁数
counter hotpの時必須 - カウンター
period totpのときオプション 30 totpの生成間隔(秒)

全部入りだとこんなURIになります。

otpauth://totp/anonymous@example.com?secret=NFWG65TFPFXXK===&issuer=example&algorithm=sha256&digits=8&period=15

image.png

13
9
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
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?