2段階認証の「バックアップコード」はなぜ1回しか使えないのか?ワンタイム破棄の理由
GoogleやGitHubなどのWebサービスで2段階認証(2FA)を設定した際、8〜10桁の英数字が並んだ「バックアップコード(リカバリーコード)」を10個ほどまとめて保存するように促されます。
このコードは、一度ログインに使うと即座に無効化され、二度と同じコードではログインできない仕組みになっています。なぜ「1回限りの使い捨て(Burn after read)」として設計されているのか、そのセキュリティ上の理由と内部の仕組みについて整理しました。
1. 緊急時の「最後の砦」としての役割
バックアップコードは、日常的に使うための認証手段ではなく、万が一のトラブル時にアカウントから締め出されないための救済手段です。
- スマートフォン紛失・故障時の迂回:認証アプリ(Google Authenticator等)を入れた端末の水没や紛失、あるいはSMSが受信できない状況でも、手元にバックアップコードがあれば本人確認を突破してログインできます。
- 通常の2段階認証のバイパス:本来は「パスワード + 時間同期型のワンタイムパスワード(TOTP)」で認証するところを、このバックアップコード1つで2段階目の認証を完了させる強力な権限を持っています。
2. なぜ「1回限り(ワンタイム破棄)」なのか
通常のパスワードと異なり、バックアップコードが1回使った瞬間に破棄される理由は、主にセキュリティリスクの最小化にあります。
永続的なバックドア化を防ぐ
もしバックアップコードが何度も再利用可能だった場合、それは「第2の固定パスワード」と同じになってしまいます。
バックアップコードは紙に印刷したり、パスワードマネージャーのメモ欄に控えておくことが推奨されるため、紛失や盗難、のぞき見(ショルダーハック)のリスクが通常の認証コードよりも高くなります。1度使われたコードをその場で無効化することで、第三者にコードを知られても再侵入される隙をなくしています。
漏洩時の被害範囲を限定する
発行された10個のコードのうち、1つが万が一漏洩して不正ログインに使われたとしても、即座に消費・失効するため、同じコードによる継続的な不正アクセスを防げます。また、ログイン通知を受け取ったユーザーは、残りのバックアップコードを無効化(再生成)して防御策を講じる時間を稼ぐことができます。
3. サーバー側での保存方法と安全性
「手元の紙に印刷したコードをサーバーはどうやって照合しているのか」という点にもセキュリティ上の工夫があります。
実は、サーバー側でもバックアップコードは平文(そのままの文字列)では保存されていません。通常のログインパスワードと同様に、ソルト付きハッシュ化(bcryptやArgon2など) された状態でデータベースに記録されています。
- 入力時:ユーザーがログイン画面でバックアップコードを入力する。
- ハッシュ照合:サーバー側で入力されたコードをハッシュ化し、保存されている未使用ハッシュ値の一覧と突き合わせる。
- 即時無効化:一致したレコード(またはハッシュ値)をデータベースから即座に削除、あるいは「使用済み」フラグを立てて二度と照合されない状態にする。
この仕組みにより、仮にサービス提供元のデータベースが外部に流出したとしても、攻撃者がバックアップコードの平文を復元することは極めて困難です。
4. バックアップコードの適切な運用
バックアップコードは「アカウント復旧のための最後の鍵」となるため、扱い方にも注意が必要です。
[check]
- 平文のままクラウドに置かない:Googleドライブやメール本文、スマホの標準メモアプリなどにそのままテキストで保存するのは避ける
- 物理印刷または暗号化保管:紙に印刷して金庫などに保管するか、暗号化されたパスワードマネージャーのセキュアメモに保存する
- 残り枚数が減ったら再生成する: