【ITニュース解説】Understanding HOTP and TOTP in Two-Factor Authentication
2025年09月29日に「Dev.to」が公開したITニュース「Understanding HOTP and TOTP in Two-Factor Authentication」について初心者にもわかりやすく解説しています。
ITニュース概要
2段階認証のワンタイムパスワード(OTP)は、認証アプリで主流だ。利用で進むHOTPと時間で更新されるTOTPがあり、どちらも共有秘密鍵とカウンターまたは時刻を基に、ハッシュ化と加工で生成される。セキュリティ強化に欠かせない技術である。
ITニュース解説
現在のWebサイトでは、ユーザー名とパスワードだけではセキュリティが十分とは言えない。フィッシング詐欺や不正アクセスからアカウントを保護するため、二要素認証(2FA)と呼ばれる追加のセキュリティ層が広く利用されている。これは、あなたが知っているもの(パスワード)だけでなく、あなたが持っているもの(スマートフォンなど)を使って本人確認を行う仕組みである。
二要素認証にはいくつかの実装方法があるが、携帯電話へのSMSによるワンタイムパスワード(OTP)送信、GitHubのようなプッシュ通知、そしてGoogle AuthenticatorやMicrosoft Authenticator、Authyといった認証アプリが挙げられる。この中でも、認証アプリは最も広く使われている方法だ。これらのアプリは、一定のルールに基づいて一度だけ有効なパスワードを生成する。このワンタイムパスワードの生成方法には、主に「オンデマンドで生成されるHOTP(Hash-based OTP)」と、「一定期間ごとに自動で更新されるTOTP(Time-based OTP)」の二種類がある。
Webサイトで二要素認証を有効にする際、多くの場合、認証アプリでスキャンするためのQRコードが表示される。このQRコードには、認証に必要なすべての情報が特殊なURI形式でエンコードされている。具体的には「otpauth://totp/発行者:アカウント名?secret=BASE32シークレット&issuer=発行者名&algorithm=SHA1&digits=6&period=30」のような形式だ。このURIの各要素は、otpauth://totpが使用する方式(TOTPまたはHOTP)を示し、発行者:アカウント名はどのサービスのアカウントかを識別するのに役立つ。最も重要なのはsecretで、これはサーバーとあなたの認証アプリの間で共有される秘密鍵であり、Base32と呼ばれる形式でエンコードされている。Base32エンコードは、データを32種類の英数字(A-Zと2-7)に変換する方法で、読みやすさや誤入力の防止に役立つ。algorithmはOTP生成に使われるハッシュアルゴリズム(通常はSHA-1、SHA-256、SHA-512など)を示し、digitsはOTPの桁数(6桁または8桁)、periodはTOTPの場合の有効期間(秒単位、デフォルトは30秒)をそれぞれ示す。認証アプリはこの情報を読み取り、自動でOTPの生成を開始する。
HOTP、すなわちハッシュベースのワンタイムパスワードは、カウンターに基づいた認証方式である。サーバーとあなたの認証アプリは、設定時に共有された秘密鍵と、OTPが生成されるたびに増えるカウンターの両方を保持している。OTPの生成手順は次の通りだ。まず、共有された秘密鍵と現在のカウンター値を結合する。次に、これらを指定されたハッシュアルゴリズム(通常はSHA-1)を使ってHMACハッシュ化する。HMACは、秘密鍵とメッセージを使って生成される特殊なハッシュ値で、メッセージが改ざんされていないことや、送信者が秘密鍵を知っていることを証明する際に使われる。SHA-1は、データを一方向性の固定長の値に変換するハッシュアルゴリズムの一つで、入力が少しでも変わると出力が全く異なる値になる特性を持つ。このHMAC結果は20バイト(160ビット)のコードとなるが、これをそのまま表示するわけにはいかないため、動的切り詰めという処理を適用して、ユーザーが見慣れた6桁または8桁の数字のOTPを抽出する。生成されたOTPはサーバーに送信され、サーバーも独自に同じ計算を行ってそのOTPが正当なものであるか検証する。この方式では、OTPが一度使用されるとカウンターが進むため、同じOTPを再度使うことはできない。
TOTP、すなわち時間ベースのワンタイムパスワードは、HOTPの概念を応用しつつ、カウンターの代わりに現在の時刻を利用する方式である。サーバーとクライアントは、まず現在のUnix Time(1970年1月1日午前0時UTCからの経過秒数)を指定された期間(period)で割った商(小数点以下を切り捨てた値)を計算し、これを「タイムステップ」と呼ぶ。このタイムステップが、HOTPにおけるカウンターとして機能する。次に、共有された秘密鍵とこのタイムステップを結合し、HOTPと同様にHMACハッシュ化を行う。最後に、動的切り詰めを適用して6桁または8桁のOTPを生成する。このOTPは、計算されたタイムステップに対応する期間(例えば30秒)のみ有効である。サーバーとクライアントの時計が正確に同期している限り、両者は独立して同じOTPを生成できるため、認証が成功する。しかし、両者の時計に大きなズレがあると、生成されるタイムステップが異なり、OTPも一致しなくなるため、認証が失敗する可能性がある。このため、多くのサーバーでは、多少の時計のズレを許容するために、現在のタイムステップだけでなく、前後1〜2ステップのOTPも有効とみなす「検証ウィンドウ」を設けている。
動的切り詰めは、HOTPとTOTPの両方で共通して用いられる重要なステップだ。HMACによって生成された20バイトの長いハッシュ値から、ユーザーが入力しやすい短い数字列のOTPを抽出する役割を担う。具体的には、まずHMAC結果の最後のバイトを取り出し、その値と0x0F(10進数の15)の間でビット単位のAND演算を行うことで、オフセット値(開始位置)を計算する。ビット演算とは、コンピュータがデータを扱う最小単位であるビット(0か1)に対して直接行う計算のことである。次に、計算されたオフセット位置から始まる4バイトを選択する。この4バイトを31ビットの整数値に変換するが、この際、最上位ビット(符号を示すビット)は無視する。最後に、この31ビット整数値を10のd乗(dはOTPの桁数、通常は6または8)で割った余りを計算する。これにより、必ず指定された桁数(例えば6桁)の数値OTPが得られる。
HOTPとTOTPにはいくつかの違いがある。HOTPはカウンターに基づいており、OTPは一度使用されると無効になる。認証を成功させるためには、サーバーとクライアントのカウンター値が同期している必要がある。主にハードウェアトークンや一部の銀行アプリなどで利用される。一方、TOTPはタイムステップに基づいており、OTPは特定の時間期間(例:30秒)のみ有効だ。サーバーとクライアントの時計が同期していることが認証成功の条件となる。スマートフォン向けの認証アプリやWebアプリケーションで広く利用されている。
二要素認証を導入する上での注意点として、ハッシュアルゴリズムはSHA-1以上の強度を持つものを使用することが推奨される。また、前述の通りTOTPでは時計の同期が重要だが、サーバー側で検証ウィンドウを設定することで、軽微な時計のズレに対応できる。そして、セキュリティの観点から、SMSベースのOTPはSIMスワップ攻撃などのリスクがあるため、可能な限り認証アプリベースのHOTPやTOTPを利用することが望ましい。これらの技術は、インターネットサービスをより安全に利用するための基盤となっている。