PKCE(Proof Key for Code Exchange)は、OAuth 2.0の認可コードフローをより安全にするために導入された仕組みで、特にクライアントシークレットを安全に保持できないクライアント(主にSPAやモバイルアプリ) において重要です。PKCEは、**認可コードの横取り攻撃(Authorization Code Interception Attack)**を防ぐために使われます。
PKCEの仕組み
PKCEでは、認可コードフローに「コードチャレンジ」と「コードバリファイア」の2つの追加パラメータを導入します。これにより、攻撃者が認可コードを横取りしても、アクセストークンを取得することが難しくなります。
主な用語
- コードバリファイア(Code Verifier): クライアントがランダムに生成する値で、アクセストークンをリクエストする際に使用されます。
- コードチャレンジ(Code Challenge): コードバリファイアをハッシュ化した値で、認可リクエスト時に送信されます。
PKCEの動作フロー
-
クライアントがコードバリファイアを生成
- クライアント(例:SPA)はランダムな値であるコードバリファイアを生成します。これは高いエントロピー(予測困難性)を持つランダムな文字列です。
-
コードチャレンジの作成
- コードバリファイアをSHA-256でハッシュ化してURLエンコードし、コードチャレンジを生成します。
-
plain
方式も使用可能ですが、S256
(SHA-256を使ったハッシュ化)が推奨されます。
-
認可リクエスト
- クライアントは認可サーバー(IdP)に認可コードをリクエストするとき、コードチャレンジと使用するハッシュメソッド(
code_challenge_method
)を含めます。 - リクエスト例:
GET /authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&scope=SCOPE&state=STATE&code_challenge=CODE_CHALLENGE&code_challenge_method=S256
- クライアントは認可サーバー(IdP)に認可コードをリクエストするとき、コードチャレンジと使用するハッシュメソッド(
-
認可サーバーの応答
- 認可サーバーは認証後、クライアントに認可コードを発行し、リダイレクト先に送信します。
-
アクセストークンリクエスト
- クライアントは認可コードを受け取った後、アクセストークンをリクエストします。このとき、初回に生成したコードバリファイアを含めてリクエストします。
- リクエスト例:
POST /token grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID&code_verifier=CODE_VERIFIER
-
認可サーバーによる検証
- 認可サーバーはコードチャレンジを取り出し、クライアントから送られたコードバリファイアをハッシュ化してコードチャレンジと比較します。
- 一致すれば認証が成功し、アクセストークンを発行します。
PKCEのメリット
- 認可コードの横取り攻撃を防止: 攻撃者が認可コードを横取りしたとしても、適切なコードバリファイアを持っていなければアクセストークンを取得できません。
- 安全性の向上: クライアントシークレットを使用しないため、SPAやモバイルアプリのようにクライアントシークレットを安全に保持できない環境で安全に認可フローを実装できます。
PKCEが特に有効なケース
- SPA(Single Page Application): JavaScriptで実行されるアプリケーションはクライアントシークレットを保持できないため、PKCEを利用することでセキュリティを高められます。
- モバイルアプリ: モバイルアプリも、ユーザー端末にアプリがインストールされるため、クライアントシークレットを安全に保持することが難しいです。
まとめ
PKCEは、OAuth 2.0認可コードフローにおける安全性を高めるための拡張で、特にクライアントシークレットを安全に保持できないクライアントにとっては必須の仕組みです。これにより、認可コードの横取り攻撃を防ぎ、アクセストークン取得プロセスをより安全にします。