TOTP コードの仕組み

TOTP コードとは、認証アプリとサーバーがそれぞれ独立に計算する6桁の数字です。入力は2つだけ、共有シークレットキーと、30秒のウィンドウに区切られた現在時刻です。コード自体は設定時に送信されることがなく、シークレットについての情報も運びません。それでも両者が同じ数字にたどり着くのは、TOTP が魔法でも乱数でもなく、公開されたアルゴリズム(RFC 6238)を同じ入力に適用した結果だからです。この記事では計算を最初から最後までたどり、「間違ったコード」がほぼ常に時計の問題である理由を説明し、第二要素が第二要素であり続けるかどうかを決める取り扱いルールを整理します。各ステップは、ブラウザ内でローカルにコードを計算するTOTP ジェネレーターで自分で実行できます。

2つの入力、1つのコード:シークレットと時計

2要素認証を有効化すると、サービスはランダムなシークレットを生成します。通常は20バイトで、Base32 文字列として表示され、利便性のために QR コードにも符号化されます。このシークレットが保管される場所は正確に2か所、サービスのデータベースとあなたの認証アプリです。その瞬間から、ログインは同期した計算になります。両側が現在の Unix 時刻を取り、タイムステップ(ほぼすべてのサービスで30秒)で割り、得られたカウンタをシークレットとともにハッシュ関数へ投入します。出力が一致した者が、シークレットの保持者として扱われます。

この設計の優雅さは、何を省いたかにあります。送信すべきチャレンジはなく、届けるべきコードもなく、ネットワークの往復もなく、ログインごとに傍受できるものも何もありません。「ワンタイム」性は時計から来ます。カウンタが30秒ごとに変わり、古い出力は無価値になるからです。同時に、壊れうるものは正確に2つしかないことも意味します。シークレットと、時刻です。TOTP の失敗も TOTP の盗難も、ほぼすべてこのどちらかに行き着きます。

計算を一歩ずつ

カウンタはまず8バイトのビッグエンディアン整数として書かれます。両者が合意した固定幅の符号化です。次にそのメッセージは、シークレットを鍵とする HMAC に通されます。使用するハッシュは合意済みのもので、既定は SHA-1、選ぶサービス向けに SHA-256 と SHA-512 も定義されています。HMAC は鍵付きの構成であり、素のハッシュではありません。カウンタをただハッシュするだけなら、アルゴリズムを知る誰もがコードを再現できてしまいますが、HMAC の出力はシークレットなしには偽造できず、逆算してシークレットを取り戻すこともできません。

ダイジェストは20バイト以上ありますが、ログイン欄が欲しいのは6桁です。その橋渡しが動的切り捨てです。ダイジェストの最後の半バイトがオフセットを選び、そのオフセットから4バイトを読み取り、最上位ビットをマスクし(符号の曖昧さを避けるため)、得られた31ビットの数を 10 の桁数乗で割った余りにします(標準の6桁なら100万)。左側はゼロで埋められます。それがあなたが入力するコードです。次のウィンドウは最初から計算し直します。コード同士を結ぶ鎖はないので、写真に撮ったコードは30秒後には無価値です。

コードが拒否されるとき:大抵は時計のせい

カウンタは時刻から導かれるので、生成側とサーバーは「現在の30秒ウィンドウはどれか」で一致しなければなりません。ほとんどのサーバーはこれを和らげ、前後のウィンドウも受け付けます(両側に1ステップずつ)。小さなずれは静かに吸収されます。その範囲を超えると、シークレットがどれほど正しくてもすべてのコードが間違いになり、失敗の見た目は桁の打ち間違いとまったく同じです。どの入力が食い違ったかのヒントもなく、ただ拒否されます。

だから、突然動かなくなった認証アプリの最初の診断は、決してシークレットではありません。コードを生成しているデバイスの時計です。手動で設定した時刻、弱った CMOS バッテリー、フライト中ずっと間違ったタイムゾーンモードだったスマートフォン、そのどれもがデバイスを1分以上ずらします。私たちのTOTP ジェネレーターがライブの時計カードを表示し、あなたのデバイスとサーバー時刻を比較するのは、まさにこのためです。日付と時刻の自動設定をオンにすれば、コードはほぼ必ずまた動き出します。リセットも、新しいシークレットも、サポートチケットも不要です。

シークレットこそが全て

儀式を取り払えば、TOTP の安全性は1つの事実に帰着します。シークレットを持つ者は、第二要素を永遠に、どこからでも持ち、サービスはそのコードとあなたのコードを見分けられません。設定時にスキャンする QR コードは、コードの画像ではありません。それはシークレットそのものにアカウントのラベルとパラメーターを添え、otpauth:// URI として整形したものです。そのスクリーンショットは、あなたの第二要素の恒久的なコピーです。

だから取り扱いルールはパスワードより厳しくなります。パスワードはサーバーが検証し、ハッシュ化して保存できますが、TOTP シークレットは両側が生の形で取り出せなければならず、ハッシュで消し去ることができません。すべてのコピーが生きているコピーです。マスターコピーは認証アプリか暗号化されたパスワードマネージャーに保管してください。サーバー側でコードを生成するウェブサイトに決して入力しないでください。見知らぬ相手に恒久的な鍵を手渡したことになります。そして決してチャットに貼らないでください。その理由は次のセクションで説明します。

シークレットを決してチャットに入れてはいけない理由

2FA シークレットをチャット(サポートとの会話、チームのチャンネル、AI アシスタント)に貼ることは、一見無害に思えます。文字列は意味不明に見え、会話は私的に感じられるからです。しかしどちらも違います。チャットは記録され、保持され、アカウントのすべてのデバイスに同期され、検索可能で、あなたの管理の及ばないサーバーで処理されます。AI チャットでは、そこに学習パイプラインと長期保持も加わります。シークレットがそこに届いた瞬間、あなたの第二要素は、テキストを保存して索引化するために設計されたシステムの中に存在することになります。

安全なパターンは、シークレットが存在してよい場所を3種類だけにすることです。サービスのデータベース、あなたの認証アプリかパスワードマネージャー、そしてあなたが管理するデバイス上でのローカル計算。当サイトのTOTP ジェネレーターはこの通りに作られています。シークレットはページのメモリ内だけに保持され、再読み込みで破棄されます。もしシークレットを既に貼ってはいけない場所に貼ってしまったら、焼けたものとして扱ってください。サービスで2要素認証をオフにしてからオンに戻して新しいシークレットを発行し、認証アプリを再登録し、ついでにパスワード自体をパスワード漏洩チェックで確認してください。

TOTP が止められないもの

TOTP はパスワードの盗難、クレデンシャルスタッフィング、データベース漏洩を打ち破ります。パスワードを知っているだけでは、もはや不十分です。しかしリアルタイムのフィッシングは打ち破れません。あなたの資格情報を本物のサービスへ中継し、コードを求める偽のログインページは、その30秒のウィンドウ内にコードをそのまま渡せてしまいます。コードが証明するのはシークレットの保持であって、本物のサイトと話していることではないからです。セッション Cookie の盗難もこれを同じように完全に迂回します。コードは一度しか確認されないからです。

だからこそ、パスキーとハードウェアセキュリティキーが最上位の領域で TOTP を置き換えつつあります。証明をサイトのオリジンに結びつけ、中継者が盗める入力可能なものを何も残さないからです。TOTP は今も強力で普遍的な基準であり、電話ネットワークの弱点を引き継ぐ SMS コードよりはるかに優れていますが、目を開いて導入すべきです。シークレットはマスターキーのように守り、バックアップコードは別の場所に保管し、時計を正直に保ち、サービスが提供するならパスキーを優先してください。

出典

よくある質問

コードからシークレットを導き出すことはできますか?

できません。各コードは切り捨てられた HMAC 出力であり、HMAC は一方向の構成です。いくつコードを観察しても、攻撃者は鍵を再構成できず、鍵なしに将来のウィンドウのコードを予測することもできません。第二要素が実際に盗まれる経路は、シークレット自体の漏洩(スクリーンショット、チャット、サーバー側ジェネレーター)と、ウィンドウ内に新鮮なコードを中継するリアルタイムフィッシングです。

なぜサービスは前後のコードも受け付けるのですか?

許容のためです。あなたのデバイスとサーバーがウィンドウの切り替わる正確な秒で一致することはまれで、小さな時計のずれもありふれているため、ほとんどのサーバーは隣接するタイムステップのコードも受け付けます。これにより有効なウィンドウは30秒からおよそ90秒に広がります。意図的な使いやすさのトレードオフで、写真に撮ったコードは1分後にはやはり無価値です。

SHA-1 は「破られた」のに、SHA-1 の TOTP はまだ安全ですか?

この構成では安全です。有名な SHA-1 攻撃が破るのは衝突耐性であり、それが重要なのは署名と証明書です。HMAC の安全性は衝突耐性に依存しません。鍵付き構成が擬似ランダム関数のように振る舞うことに依存します。そして、観察した出力から TOTP シークレットを復元したりコードを偽造したりする実用的な攻撃は存在しません。サービスは SHA-256 を選ぶこともできます。当サイトのジェネレーターは3つすべてに対応しています。