RFC 8705: OAuth 2.0 Mutual TLS
RFC 8705 は、TLS クライアント証明書を使ったクライアント認証とトークンバインディングの仕様です。このドキュメントでは、mTLS の仕組みと実装方法を解説します。
第1部: 概要編
mTLS とは何か?
mTLS(Mutual TLS)は、TLS ハンドシェイク時にクライアントもサーバーに対して証明書を提示する仕組みです。
通常の TLS(サーバー認証のみ):
クライアント ─── TLS ───► サーバー
証明書提示
「私は example.com です」
Mutual TLS(相互認証):
クライアント ─── TLS ───► サーバー
証明書提示 ◄───────────── 証明書提示
「私は client-A です」 「私は example.com です」
RFC 8705 の 2 つの機能
| 機能 | 説明 |
|---|---|
| クライアント認証 | クライアント証明書でクライアントを認証 |
| 証明書バインドトークン | アクセストークンをクライアント証明書にバインド |
なぜ mTLS が必要なのか?
従来の方式の問題
| 方式 | 問題 |
|---|---|
| client_secret_basic | シークレットがネットワークを流れる |
| client_secret_post | シークレットがネットワークを流れる |
| private_key_jwt | JWT のリプレイ攻撃リスク |
| Bearer Token | 盗まれたら誰でも使える |
mTLS の解決策
mTLS クライアント認証:
- クライアント証明書は TLS 層で検証
- 秘密鍵は一切ネットワークを流れない
- PKI インフラで信頼性を担保
証明書バインドトークン:
- トークンが特定の証明書にバインド
- 証明書を持たない攻撃者はトークンを使用不可
第2部: 詳細編
クライアント認証方式
RFC 8705 では 2 つのクライアント認証方式を定義。
1. PKI Mutual TLS(tls_client_auth)
CA が発行した証明書を使用。認可サーバーは証明書の Subject を検証。
クライアント登録時:
{
"client_id": "s6BhdRkqt3",
"token_endpoint_auth_method": "tls_client_auth",
"tls_client_auth_subject_dn": "CN=client-app,O=Example Inc,C=US"
}
トークンリクエスト:
POST /token HTTP/1.1
Host: auth.example.com
Content-Type: application/x-www-form-urlencoded
# TLS クライアント証明書が提示されている
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&client_id=s6BhdRkqt3
注意: client_secret は不要。TLS 層でクライアント認証が完了している。
2. Self-Signed Certificate(self_signed_tls_client_auth)
自己署名証明書を使用。認可サーバーは事前登録された証明書と照合。
クライアント登録時:
{
"client_id": "s6BhdRkqt3",
"token_endpoint_auth_method": "self_signed_tls_client_auth",
"jwks": {
"keys": [{
"kty": "RSA",
"use": "sig",
"x5c": ["MIIDQjCCAiqgAwIBAgIGATz..."]
}]
}
}
Subject DN の照合
PKI mTLS では、証明書の Subject DN を照合。
| 属性 | パラメータ | 例 |
|---|---|---|
| Subject DN | tls_client_auth_subject_dn | CN=client,O=Example,C=US |
| SAN DNS | tls_client_auth_san_dns | client.example.com |
| SAN URI | tls_client_auth_san_uri | https://client.example.com |
| SAN IP | tls_client_auth_san_ip | 192.168.1.1 |
| SAN Email | tls_client_auth_san_email | client@example.com |