よくある質問
TOTP は実際にどう動いていますか?
TOTP(RFC 6238)は HOTP(RFC 4226)のカウンタを `floor(unix_timestamp / period)` に置き換えたものです。サーバとクライアントは秘密を共有し、`HMAC-SHA-1(secret, counter)` を計算してから動的トランケーションで 6 桁の 10 進コードを取り出します。両者が同じ時刻と同じ秘密を使うため、30 秒ごとに同じコードに到達します。サーバ側は 1 ウィンドウ(±30 秒)の差異を許容するのが一般的で、それより大きくずれるとコードが食い違い、再同期が必要になります。
TOTP と HOTP の違いは?
HOTP はコードを生成するたびにカウンタを増やしますが、TOTP は現在時刻をカウンタとして使います。HOTP のコードはオフラインでも生成でき、ウィンドウ内なら任意の順序で使えますが、サーバ側はリプレイ検知と、ユーザが余分にコードを生成した場合の再同期のためにスライディングカウンタを管理する必要があります。TOTP では時計を介して暗黙的に両者がカウンタに合意できるため、運用が単純になります。今日の消費者向け 2FA はほぼ TOTP で、HOTP は RSA SecurID の旧モデルのような古いハードウェアトークンに残っています。
SHA-1 がまだ使われているのはなぜですか? 破られていませんか?
SHA-1 の衝突耐性は破られています(2017 年の SHAttered 攻撃)。しかし HMAC-SHA-1 は今も安全です。攻撃モデルが違い、攻撃者は秘密を知らずにタグを偽造する必要があり、同じ平文ハッシュを持つ 2 つのメッセージを見つけるだけでは不十分だからです。NIST は SP 800-107r1 まで HMAC-SHA-1 を MAC 用途として承認しており、RFC 6238 も SHA-1 を既定とします。新しい発行者は SHA-256 や SHA-512 を使えますが、認証アプリのすべてが SHA-1 をサポートし、長いバリアントは一部しか対応していないため、相互運用性のために SHA-1 が残っています。
シークレットは正しそうなのにコードが合いません
よくある原因は 3 つです。**時計のずれ**: TOTP はデバイス時計が NTP 真値から 30 秒以内であることを要求します。設定 / システム時刻を確認し、自動同期をオンにしてください。**パディング**: 一部のサーバは末尾 `=` 付きで base32 シークレットを返し、別のサーバはそれを削除します。両者は等価にデコードされるはずですが、まれにバグのある実装が片方の形で壊れます。**アルゴリズム不一致**: `algorithm=SHA512` を含む `otpauth://` URL は、SHA-1 のコードを生成するアプリと一致しません。otpauth 形式が与えられている場合はそのパラメータに従い、上書きしないでください。
ログインと同じブラウザで TOTP を生成するのは危険ですか?
部分的に危険です。「2 つ目の要素」という発想は、パスワードを盗まれてもログインには別デバイス(スマホ)が必要、というものです。TOTP のシークレットがパスワードと同じブラウザセッションにあると、マルウェア感染やブラウザ拡張の侵害で両方を一度に奪われます。日常のアカウントセキュリティでは TOTP を別デバイス(スマホの認証アプリ、または YubiKey などのハードウェアキー)に置いてください。本ウェブツールは開発、スクリプト自動化、スマホを失った際の復旧、脅威モデルが異なるステージング環境などに使ってください。
TOTP と WebAuthn / passkey はどちらが優れていますか?
ほとんどの用途で WebAuthn(と passkey の UX 層)は厳密に TOTP より安全です。TOTP はサーバとクライアントで秘密を共有するため、データベース侵害や、リクエストをプロキシするフィッシングサイトで第二要素が盗まれ得ます。WebAuthn は公開鍵暗号でオリジンに紐づくため、`github.com` 用の passkey は、ユーザが騙されても `github.evil.com` に対してリプレイできません。TOTP の今日の優位は普及度です。レガシーサービスのほとんどが対応し、対応ハードウェアトークンが安く、復旧フローがよく確立されています。新規システムでは passkey を既定とし、TOTP をフォールバックとするのが筋であり、逆ではありません。
関連する概念
TOTP(Time-based One-Time Password、RFC 6238、2011 年 5 月)は HOTP(RFC 4226、2005 年)に小さなラッパーを被せたものです。どちらも共有秘密から HMAC-SHA-1 と動的トランケーションで 6 桁のコードを取り出します。違いはカウンタです。HOTP はコード生成ごとにカウンタを増やし、TOTP は `floor(unix_time / 30)` でカウンタを計算します。30 秒ウィンドウは事実上の標準ですが必須ではなく、otpauth URL の period パラメータで変更できます。多くの認証アプリは 30 秒を仮定し、それ以外の値を無視します。
日々の実装で重要な点が 3 つあります。共有秘密は通常、`otpauth://totp/<label>?secret=<base32>&issuer=<name>&algorithm=SHA1&digits=6&period=30` URL を含む QR コード経由でアウトオブバンドに交換します。QR コード自体は単なる伝送経路で、デコードすればただの base32 シークレットです。サーバ側の検証はクロックスキューを許容するため通常 ±1 ウィンドウのドリフトを認めます。バックアップコード(セットアップ時にユーザが印刷する 1 回限りの予備コード)は、スマホを失った場合の標準的な復旧手段です。
TOTP の周囲には 3 つの隣接技術があります。**HOTP** はカウンタベースの先祖で、一部のハードウェアトークン(RSA SecurID 旧モデル、Yubico の HOTP スロット)で今も使われています。**SMS ベースの 2FA** はテキストメッセージでコードを送るもので、便利ですが SIM スワップ攻撃に弱く、NIST(SP 800-63B)は高価値アカウントでの廃止を進めています。**WebAuthn / passkey**(FIDO2)はリライング・パーティのオリジンに紐づく公開鍵暗号を使い、フィッシングを構造的に不可能にします。第二要素の世界はこちらに向かっており、TOTP は移行未済のサービス向けのロングテール的なフォールバックになっていきます。YubiKey のようなハードウェアトークンは 3 つすべて(OATH-HOTP / OATH-TOTP の TOTP スロット、加えて FIDO2)に対応しています。