TOTP / 2FA コードデバッガー

TOTP / 2FA コードを生成・デバッグします。RFC 6238 の完全な導出、ドリフト窓での検証、otpauth:// の解析まで、すべてブラウザ内で。

時刻

コードを見るにはシークレットを入力してください。

この設定の otpauth:// URI
otpauth://totp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30

その6桁は本当は何なのか

TOTP コード — 認証アプリが30秒ごとに更新する数字 — はランダムでもなく、どこかに保存されているわけでもありません。あなたの電話とサーバーの両方で、すでに共有されている二つのもの、すなわち二要素認証を有効にしたときに一度設定されたシークレットと、現在時刻から計算されます。両者が独立して計算できるため、ログイン時に両者の間で何かが行き来する必要はありません。サーバーは同じ計算を実行し、その答えがあなたのものと一致するかを確認するだけです。

TOTP(RFC 6238)は、より古い方式である HOTP(RFC 4226)の上の薄い層です。HOTP はシークレットとカウンターをコードに変えます。TOTP は、カウンターを Unix 紀元からの時間ステップ数に設定しただけの HOTP です。それがすべての考え方です。現在の Unix 時刻をステップ長(既定で30秒)で割り、その結果を HOTP に渡すのです。コードが検証されないとき、答えはほぼ必ず導出のどこかに見えているので、このツールはその計算の各ステップを表示します。

導出、一歩ずつ

五つのステップがシークレットと時刻からあなたが入力する数字へと導きます。ツールは各ステップを表示するので、ご自身の実装と比較できます。

  • カウンター。Unix 時刻を秒で取り、T0(実際の運用ではすべて0)を引き、周期で割って切り捨てます。30秒ステップでは、同じ半分の分にあるどの瞬間も同じカウンターになるため、コードはその分だけ持続します。
  • HMAC。カウンターを8バイトの big-endian として書き、選んだハッシュで HMAC(シークレット, カウンター) を計算します。ほとんどのアプリは SHA-1 です。これは SHA-1 で20バイトのダイジェスト(SHA-256 で32、SHA-512 で64)を生みます。
  • オフセット。ダイジェストの最終バイトの下位4ビットを取ります。これは0から15の数で、ダイジェストのどこを読むかを示します — 動的切り詰めであり、同じシークレットが常に同じバイトを使うわけではありません。
  • 31ビット値。オフセット位置から4バイトを読み、最上位ビットをマスクします(符号の混乱を避けるため)。31ビットの整数が残ります。
  • コード。その整数を 10^桁数 で割った余りをとり、左を0で埋めます。6桁がほぼ普遍的な選択です。7桁と8桁も存在し、許容されています。

最上位ビットのマスクと剰余だけが損失のあるステップです。多くの異なるダイジェストが同じ6桁に写りますが、それで構いません。コードは、生きている30秒の間だけ推測しにくければよく、永遠に一意である必要はないからです。

なぜコードが合わないのか — よくある三つの原因

TOTP の不一致はエラーメッセージを伴いません。コードが単に間違っているだけです。実際にはほぼ必ず次の三つのどれかで、ここのパネルはそれらを見分けるために並んでいます。

  • シークレットが誤った形式で読まれた。認証アプリのシークレットは Base32 ですが、同じ文字を hex として読むと — あるいは実際は hex だったシークレットを Base32 として読むと — まったく異なるバイトとまったく異なるコードになります。形式の切り替えを操作し、期待どおりのコードを出すのはどちらか見てください。
  • パラメーターが異なる。圧倒的な既定は HMAC-SHA-1、6桁、30秒周期です。SHA-256、8桁、あるいは60秒ステップを使うサーバーは、既定のままのアプリと食い違います。otpauth:// URI は三つすべてを運ぶので、QR を読み取ればそれらを正しく得られますが、シークレットを手入力するとしばしばそうなりません。
  • 時計がずれた。TOTP は両者が時刻について一致していることを前提とします。電話の時計が1分進んでいれば、そのコードはサーバーより1分先です。ドリフト窓はそのためにあります。今の両側のステップに対してコードを検証すると、一致するかだけでなく時計がどれだけずれているかも分かります。

RFC 6238 は各側で最大1ステップの検証窓を推奨します。通常の時計ずれと切り替わりの瞬間の競合を吸収するのに十分で、探索空間を必要以上に広げません。このツールは既定で ±1 とし、デバッグ時に広げられます。

シークレット、Base32、otpauth:// URI

シークレットは設定時に一度共有され、あとはすべてそこから導出されます。認証アプリはそれを Base32(RFC 4648)で符号化します — 文字 A–Z と 2–7 のアルファベットで、見間違えやすい文字を避け、QR の下に印刷されても生き残ります。このツールは既定で Base32 を読み、アプリが読みやすさのために加える空白と大文字小文字を無視し、さらに hex も受け付けるので、シークレットが生バイトで与えられる RFC 6238 のテストベクターを再現できます。

設定時に読み取る QR コードも魔法ではありません。シークレットとすべてのパラメーターを運ぶ平文の otpauth:// URI を符号化しているだけです。ここに貼り付けてフィールドを埋めるか、フィールドから作ってアプリ間で設定を移せます。

otpauth://totp/GitHub:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=GitHub&algorithm=SHA1&digits=6&period=30

受け付けるのは totp 型だけです。otpauth://hotp URI は周期ではなくカウンターを運び、それを TOTP として扱えば黙って誤ったコードを生むので、推測せず拒否します。

アルゴリズム、桁数、周期

RFC 6238 は HMAC-SHA-1、SHA-256、SHA-512、6桁から8桁、任意のステップ長を許します。実際には世界は SHA-1、6桁、30秒に落ち着き、ほとんどのアプリはその組み合わせしか実装していません。ですから他を選んだサーバーは利用者のアプリが追随することを期待するほかなく、多くは追随しません。相互運用のための安全な選択は退屈なものです。

SHA-1 の問題は直接扱う価値があります。このサイトのハッシュツールは SHA-1 を壊れていると記すからです。どちらの主張も正しいのです。SHA-1 はデジタル署名には使えません。攻撃者が衝突 — 同じハッシュを持つ二つの文書 — を作れるからです。TOTP はその性質に依存しません。その安全性は HMAC 内のシークレット鍵から来るのであり、ハッシュの衝突耐性からではなく、HMAC-SHA-1 は健全なままです。ここで SHA-256 を使うのは擁護できますが得るものは少なく、SHA-1 しか行わないアプリとの相互運用性を犠牲にします。

このツールが守るものと守らないもの

ここのすべてはあなたのブラウザで実行されます。HMAC は Web Crypto API であなたの端末上で計算され — ハッシュツールと HMAC ツールが使うのと同じプリミティブです — 入力したもの — シークレット、コード、otpauth URI — は何もアップロード・保存・記録されません。これはコードがクライアント側であることの性質であり、信じてもらうべき約束ではありません。

とはいえ TOTP のシークレットは第二要素です。それを持つ者は誰でもあなたのコードを生成できます。本番のシークレットをどのウェブページ — このページを含む — に貼り付けても、クリップボードに、場合によってはブラウザ履歴にも入るので、パスワードと同じ注意で扱い、仕組みを理解したいだけのときは使い捨てやテスト用のシークレットを選んでください。このツールはデバッグと学習のためにあり、あなたの本物の第二要素が住む場所ではありません。

よくある質問

私のシークレットはサーバーに送信されますか?
いいえ。コードは Web Crypto API を使ってブラウザ内で計算され、入力したものは何もアップロードも記録もされません。TOTP のシークレットは第二要素なので、本番のものを貼るときはやはり注意してください。どんなテキストとも同じくクリップボードやブラウザ履歴を通ることがあります。
なぜコードが私の認証アプリと合わないのですか?
ほぼ必ず次の三つのどれかです。シークレットが誤った形式で読まれた(Base32 か hex か)、パラメーターが既定と異なる(多くのアプリは SHA-1、6桁、30秒周期)、または端末の時計がずれた。導出パネルが最初の二つを切り分け、± のドリフト窓での検証が三つ目を明らかにします。
TOTP と HOTP の違いは何ですか?
HOTP(RFC 4226)はシークレットと、使うたびに増えるカウンターからコードを計算します。TOTP(RFC 6238)は同じ構成で、カウンターを Unix 紀元からの時間ステップ数に設定するので、コードはボタン押下ではなく時計とともに変わります。TOTP は認証アプリが使うものです。
他で壊れているのに、なぜ SHA-1 が既定なのですか?
SHA-1 は衝突を構成できるため署名には壊れていますが、TOTP が基づく HMAC は衝突耐性に依存しません。その安全性はシークレット鍵に依ります。HMAC-SHA-1 は健全で、多くの認証アプリが実装する唯一のアルゴリズムなので、安全でありかつ互換な既定です。
コードを特定の時刻に固定できますか?
はい。時刻をライブから固定に切り替え、Unix タイムスタンプを入力します。するとコードは静的になり、公開されたテストベクターを再現したり(RFC 6238 は 59 や 1111111109 のような時刻で値を与えます)、過去の瞬間にどのコードが有効だったかを確認したりできます。
ドリフト窓はどれくらいの大きさにすべきですか?
RFC 6238 は各側で最大1ステップを推奨し、このツールはそれを既定とします。より広い窓はよりずれた時計を許容しますが、サーバーが受け入れるコードの集合も広げるので、トレードオフです。±1 が標準的な均衡です。
桁数と周期は何のためですか?
桁数はコードの数字の個数です。ほぼどこでも6桁、サービスがもう少し強度を求めるところで7桁か8桁です。周期はコードが有効な秒数で、既定で30秒です。両方とも otpauth:// URI に入り、両方とも二つの側で一致しなければコードは合いません。