HOTPとは?RFC 4226準拠のイベント駆動型ワンタイムパスワードの仕組みと実装ガイド

HOTPとは何か — イベントベースのワンタイムパスワード

HOTP(HMAC-based One-Time Password)は、ワンタイムパスワード(OTP)の一方式で、イベント(カウンタの増加)を基に一度だけ使えるパスワードを生成するアルゴリズムです。RFC 4226で標準化され、OATH(Initiative for Open Authentication)により提唱されました。HOTP は「共有された秘密鍵」と「共有されたカウンタ」を用い、HMAC(元来は HMAC-SHA-1)を利用して一意な数値トークンを生成します。

基本的な仕組み(概要)

  • 事前にクライアント(トークン)と認証サーバーが共通の秘密鍵 K を持つ。
  • クライアント側には「イベントカウンタ(C)」があり、トークンボタンの押下や認証要求ごとにインクリメントされる。
  • トークンは HMAC(K, C) を計算し、ダイナミックトランケーションを行って指定桁数(通常6桁)の数値を生成する。
  • サーバーは受け取ったOTPを自身のカウンタを基に検証し、一致すれば認証を成功させ、必要に応じてサーバー側のカウンタを進める。

アルゴリズムの詳細

RFC 4226 に準拠した具体的な流れは次のとおりです。

  • 入力:共有秘密鍵 K、8バイト(64ビット)でエンコードされたカウンタ C(ビッグエンディアン)、および生成桁数 Digit(通常は6)。
  • ステップ1:H = HMAC‑SHA‑1(K, C) を計算する。出力は20バイト(160ビット)。
  • ステップ2:ダイナミックトランケーション — H の最下位バイト(H[19])の下位4ビット(nibble)をオフセットとして使用し、そのオフセットから4バイト(32ビット)を抜き出す。
  • ステップ3:抜き出した32ビットの最上位ビット(符号ビット)をマスクして(0 にして)31ビットの正の整数を得る(これにより符号の影響を排除)。
  • ステップ4:その値を 10^Digit で剰余演算することで、Digit 桁の十進数 OTP を得る。

このダイナミックトランケーションは、HMAC 出力の任意の部分から値を抜き出すことで、予測を困難にします。

疑似コード(参考)

// inputs: K (secret), C (8-byte counter), digits (e.g., 6)
H = HMAC_SHA1(K, C)            // 20 bytes
offset = H[19] & 0x0f         // lower 4 bits of last byte
binary = ((H[offset] & 0x7f) << 24)
       | ((H[offset+1] & 0xff) << 16)
       | ((H[offset+2] & 0xff) << 8)
       | (H[offset+3] & 0xff)  // 31-bit positive integer
OTP = binary % (10^digits)
return OTP (zero-pad to digits)

実装上の注意点

  • カウンタ表現:C は 8 バイト(64 ビット)で送受信・保存されるのが一般的。サーバー側でのカウンタは厳密に単調増加させる必要がある。
  • 桁数:RFC 4226 は6桁を推奨するが、4〜10桁程度は利用可能。桁数が多いほど総当たり攻撃に対する耐性が向上するが、ユーザビリティは低下する。
  • HMAC ハッシュ:標準では HMAC-SHA-1 を用いる。SHA-1 の将来的な脆弱性を懸念する場合は実装や仕様で HMAC-SHA-256/512 を採用することもあるが、相互運用性に注意する。
  • トークンのリプレイ:HOTP はイベントベースであるため、同一 OTP が再利用され得る(サーバー側のカウンタが増えていないとき)。サーバーは一度受け入れたOTPを無効化するか、カウンタを進めて再利用を防ぐ。

同期と再同期(サーバー側の窓口)

物理トークンやソフトトークンのボタン押下タイミングがずれると、クライアント側カウンタがサーバー側カウンタより先行することがあります。これを吸収するため、サーバーは「ルックアヘッドウィンドウ(look-ahead window、例:100)」を持ち、現在のサーバーカウンタからウィンドウ幅だけ先までの OTP を順に検査します。もしウィンドウ内で一致するカウンタが見つかれば、そのカウンタに基づきサーバーのカウンタを進めて同期します。

ただしウィンドウを大きくしすぎると、攻撃者が試行で一致させる確率が上がるため、ウィンドウ幅は運用リスクとユーザビリティを勘案して設定します。

セキュリティ上の考慮点

  • 総当たり(ブルートフォース):OTP の桁数が小さいと試行で当てられる可能性がある。ログイン試行回数の制限やアカウントロックアウトが必須。
  • トークンの漏洩:秘密鍵 K が漏洩すればトークンを複製される。秘密鍵の安全な保管(ハードウェアセキュリティ、暗号化ストレージ)が重要。
  • フィッシング/MITM:HOTP はワンタイムであっても、攻撃者が認証直前に OTP を傍受すれば即時に利用可能。チャレンジレスポンスや追加のチャネル(端末認証、TLS)との組合せが望ましい。
  • リプレイと同期攻撃:サーバーは同一の OTP を複数回受け付けない対策を取り、カウンタを適切に更新する必要がある。

HOTP と TOTP の比較

  • HOTP:イベント駆動(カウンタ増加)。トークンのボタン押下やサーバー発行のイベントに応じて OTP が生成される。オフラインでの使用に向く(ハードウェアトークン等)。
  • TOTP(Time-based One-Time Password、RFC 6238):時刻を基に一定の時間幅(例えば30秒)ごとにOTPを生成する。時刻同期が前提。HOTP と比べて同期の必要が少なく、ユーザがトークンを「使いそこねる」リスクが低い。
  • 運用面では、TOTP の方が一般的であり、スマホ向けアプリ(Google Authenticator 等)や多くのサービスで採用されている。一方でハードウェアトークンやオフライン環境では HOTP が選ばれることがある。

導入・運用の実務ポイント

  • 初期プロビジョニング:秘密鍵 K と初期カウンタを安全に配布する必要がある。QRコードや専用キーURI(otpauth://hotp/...)を使う方法が一般的だが、配布時は TLS や物理封筒などで安全に行う。
  • バックアップとリカバリ:トークン紛失時の対応フロー(代替認証手段、身元確認プロセス)を策定する。
  • ログと監査:OTP 試行、成功/失敗のログを取り、不審な試行があればアラートを出す。
  • 更新と廃止:秘密鍵の定期的なローテーションや、廃止手続きの確立が必要。

実例とユースケース

HOTP は以下のような場面で使われます。

  • 銀行や企業のハードウェアトークン(イベントボタン押下でコードを表示)
  • オフライン端末やネットワーク接続が不安定な環境での二要素認証
  • OTP を長期間保持する必要がある特殊用途(ただしセキュリティ上の配慮が必要)

まとめ

HOTP はシンプルかつ相互運用性の高いイベント駆動型OTP方式で、RFC 4226 により標準化された実績のある技術です。導入は比較的容易ですが、秘密鍵管理、カウンタ同期、ウィンドウ幅設定、総当たり対策などの運用面の配慮が不可欠です。近年は時刻ベースのTOTPが普及していますが、HOTP が適切に選ばれる場面(ハードウェアトークンやオフライン環境)は依然として存在します。実装時は RFC の仕様に従い、最新のセキュリティベストプラクティスを適用することをおすすめします。

参考文献