チャレンジ・レスポンス認証の完全ガイド:SCRAM・SRP・PAKEからWebAuthnまでの実装とセキュリティ対策

はじめに — チャレンジ・レスポンス方式とは

チャレンジ・レスポンス方式(Challenge‑Response authentication)は、認証を行う際にパスワードや秘密鍵そのものを通信路上で送信せず、サーバ側が送る「チャレンジ(使い捨ての乱数=nonceやタイムスタンプ等)」に対し、クライアントが秘密情報を使って計算した「レスポンス」を返すことで本人性を確認する仕組みです。直接のパスワード送信を避けることで、中間者や盗聴による平文漏洩や単純なリプレイ攻撃を防止できます。

基本的な仕組み

典型的なフローは次の通りです。

  • クライアントが認証を要求する。
  • サーバが一意で使い捨てのチャレンジ(nonce)を生成してクライアントに送る。
  • クライアントは自身の秘密(パスワード、トークンのシークレット、秘密鍵など)とチャレンジを組み合わせ、適切なアルゴリズム(HMAC, ハッシュ, 暗号署名, PAKE の計算等)でレスポンスを計算してサーバに送る。
  • サーバは保持する秘密情報(またはその検証情報)を用いて同じ計算を行い、クライアントの送ったレスポンスと一致するか確認する。一致すれば認証成功。

ポイントはチャレンジが必ず「一度きり/短期間有効」であり、再利用(リプレイ)できないこと、チャレンジの生成に十分なランダム性(予測不能性)が必要なことです。

代表的な実装例・プロトコル

チャレンジ・レスポンスを採るプロトコルや方式は多数あります。代表例を挙げ、それぞれの特徴と留意点を示します。

CRAM-MD5(SASL CRAM-MD5)

古典的なSASLのメカニズムの一つで、サーバがbase64でエンコードしたチャレンジを送り、クライアントはHMAC-MD5(秘密=ユーザのパスワード)でレスポンスを作ります。通信上はパスワードを直接送らない利点がありますが、MD5 の脆弱性や、サーバがパスワードの生データ(またはそれと同等のもの)を保持する必要がある点で問題があり、現在は推奨されません。

HTTP Digest(Digest Access Authentication)

HTTPにおけるチャレンジ・レスポンスの古典で、サーバがnonceやrealmを返し、クライアントはユーザ名・パスワード・リクエスト情報を組み合わせてハッシュを作成します。平文送信を避けられますが、実装やパラメータの扱いを誤ると脆弱になり、TLS併用が事実上必須です(Digest単体はフィッシングや中間者に脆弱なケースがある)。最新のRFCはRFC 7616です。

CHAP / MS-CHAP / NTLM

CHAP(PPPで使われる)やその派生であるMS‑CHAP、Windows系のNTLMはチャレンジ・レスポンス型を採ります。MS‑CHAPv2やNTLMv1など、古いバージョンは既に多くの脆弱性が報告されており、特にMS‑CHAPv2は実質的にオフラインでのパスワード復元を許す弱点が知られています(攻撃ツールも存在)。したがって、これらは新しい設計では避けるべきです(RFC 1994、RFC 2759など)。

SCRAM(Salted Challenge Response Authentication Mechanism)

SCRAM(RFC 5802 および SCRAM‑SHA‑256 等の拡張)は、CRAMの欠点を補うために設計されたモダンな方式です。サーバ側は「ソルト+反復ハッシュで得た検証データ(verifier)」を保持し、生のパスワードを保存しなくて済む点や、メッセージ認証・相互認証の仕組みを持つ点が優れています。特に SCRAM‑SHA‑256(RFC 7677)などを採用することが推奨されます。

SRP(Secure Remote Password)および PAKE

SRP はパスワード認証に基づく鍵交換プロトコル(PAKE=Password‑Authenticated Key Exchange)の一種で、サーバ側がパスワードから導出した「検証子」を保存しつつ、対話的にゼロ知識的に正当性を証明します。特徴としてサーバが漏洩してもオフラインでパスワードを得るのが難しい点、TLSに頼らずに鍵合意と認証ができる点があります(RFC 2945 など)。

公開鍵ベースのチャレンジ・レスポンス(TLSクライアント証明書、WebAuthn/FIDO2)

公開鍵暗号を使う方式では、サーバのチャレンジに対しクライアントの秘密鍵で署名して返すことで認証を行います。TLSクライアント証明書は古典的な例。近年はWebAuthn / FIDO2が普及しており、物理セキュリティトークンやプラットフォーム認証器(TPM、Secure Enclave)を用い、チャレンジに対する署名をブラウザ経由で返すことで、フィッシング耐性の高い認証を実現します。

チャレンジ・レスポンス方式の利点

  • パスワード(あるいは秘密鍵)を平文で送らないため盗聴による直接的な漏洩が防げる。
  • 使い捨てのチャレンジやタイムスタンプによりリプレイ攻撃への耐性が高い。
  • 公開鍵方式やPAKEを使えばフィッシング・中間者攻撃に対して強力な保護を提供できる。
  • ハードウェアトークンやWebAuthnと組み合わせることでユーザ体験とセキュリティを両立できる。

主な脅威と弱点

ただし万能ではありません。主な注意点は次の通りです。

  • オフライン辞書攻撃:サーバがパスワードと同等の情報(生パスワードや単純なHMACキー)を保管している場合、サーバ側が漏えいするとオフライン攻撃が可能になる。SCRAMやPAKEはこれを軽減する設計。
  • チャレンジの不適切な生成:チャレンジが短かったり予測可能だと、攻撃者が有利になる。暗号学的に十分な乱数長を使う必要がある。
  • 中間者攻撃(MITM):プロトコルによってはチャレンジのなりすましやプロトコルメッセージの書き換えで認証バイパスが可能になる場合がある。TLSと併用する、相互認証を導入するなどの対策が必要。
  • 再利用(リプレイ):チャレンジに期限や使い捨て性がないとリプレイされる可能性がある。サーバ側でチャレンジの使用済みチェックや短い有効期間の設定が求められる。
  • アルゴリズムの陳腐化:MD5やSHA‑1等、脆弱とされるハッシュを使い続けると衝突攻撃や他の脆弱性のリスクがある。アルゴリズムの更新(アルゴリズム・アジリティ)が重要。

実装上のベストプラクティス

実際にチャレンジ・レスポンス方式を実装/採用する際の推奨事項:

  • 最新の安全な方式を選ぶ:SCRAM‑SHA‑256、PAKE(SRPや最新のPAKE)、またはWebAuthn/FIDO2を優先する。
  • 常にTLS等のトランスポート層セキュリティを併用する:チャレンジ・レスポンスは通信の一部の脅威を低減するが、プロトコルメッセージの改竄や他のメタデータ漏洩には別途対策が必要。
  • 強い乱数生成器を使う:チャレンジは十分長く(例えば128ビット以上のエントロピーが望ましい)、予測不能であること。
  • サーバ側の保存データは生パスワードではなく、ソルト付きの反復ハッシュや検証子(verifier)を保存する:SCRAMやPAKEの設計に従う。
  • 比較は定数時間で行う:タイミング攻撃による情報漏洩を避けるため。
  • チャレンジの有効期間と一意性を管理する:短い有効期間、使用済みのチャレンジの記録でリプレイを防止。
  • レートリミットと監視:ブルートフォース試行や不審な認証試行を検出・遮断する。
  • アルゴリズム・アジリティを持たせる:将来の脆弱性に備え、ハッシュやHMAC方式を変更可能にしておく。

移行と運用上の注意点

既存システムで古いチャレンジ・レスポンス(CRAM‑MD5、MS‑CHAPv2、NTLMv1 等)を使っている場合は、脆弱性が指摘されているため可能な限り新しい方式(SCRAM、SRP、WebAuthn 等)へ移行することが望ましい。移行では互換性のためにトランジションレイヤ(両方式対応)を設けたり、段階的に認証バックエンドを置き換える方策が現実的です。

まとめ:どんな場面でチャレンジ・レスポンスを使うべきか

チャレンジ・レスポンスは「パスワードや秘密を直接送信したくない」場面で有用です。しかし、安全性はどのアルゴリズム・プロトコルを選ぶか、そして実装のディテール(nonceの生成、保存データの形式、TLSの採用、アルゴリズム更新計画など)に大きく依存します。現代のシステムでは、可能ならば次の優先順位で検討してください:

  • フィッシング耐性と強力な認証が必要:WebAuthn(FIDO2)を採用
  • 既存のパスワードベースで相互認証・安全な検証をしたい:SCRAM‑SHA‑256 や PAKE(SRP)を採用
  • 古いCRAM/CHAP/NTLM等を見かけたら、速やかに非推奨とし代替方式へ移行

最後に

チャレンジ・レスポンスは古くからある重要な認証パターンであり、正しく設計・運用すれば有効なセキュリティ手段です。しかし「方式名」だけで安全とは言えず、最新の暗号実装、プロトコル設計、運用(TLS・乱数・保存データ保護・監視)と組み合わせて初めて十分な安全性が得られます。導入時は既知の脆弱性情報や標準(RFCや最新仕様)を参照し、適切に設計・レビューしてください。

参考文献