TLS証明書の名前不一致:クライアントは何と何を比べているのか(RFC 9525)
TLSクライアントが証明書のSANと何を照合するのかをRFC 9525に沿って整理します。参照識別子、DNS-IDとIP-ID、Common Nameの禁止、ワイルドカードの規則、不一致時の扱いとチェックリスト。
ブラウザやHTTPクライアントが「証明書の名前が一致しない」として接続を切るとき、クライアントは2つのものを突き合わせています。ひとつはクライアントが接続しようとした名前やアドレス、もうひとつはサーバー証明書に書かれた名前です。この照合ルールを定める現行のIETF文書がRFC 9525「Service Identity in TLS」です。2023年11月にProposed Standardとして発行され、RFC 6125を廃止(obsolete)しています。
RFC 9525はTLSだけでなく、DTLSや、TLSハンドシェイクを使うQUICのようなプロトコルにも適用される前提で書かれています(§1.4.1)。この記事ではHTTPSでよく出会うケースを中心に説明します。
参照識別子と提示識別子
RFC 9525は照合の両側を次の用語で区別します(§1.5)。
- 参照識別子(reference identifier):クライアントが期待する識別子です。ユーザーが入力したURL、事前の設定、Webページ内のリンクといったクライアント側の入力から得たソースドメイン(source domain)と、必要に応じてアプリケーションサービス種別から作ります。
- 提示識別子(presented identifier):サーバーがPKIX証明書の中で示す識別子です。1枚の証明書に複数入っていることがあります。
中心となる規則は§6.1.1にあります。クライアントは受け入れ可能な参照識別子のリストを作らなければならず(MUST)、そのリストはサーバーが提示した識別子とは独立に作らなければなりません(MUST)。証明書に書かれた名前を見てリストを埋めてしまえば、検証の意味がなくなるからです。
DNSの名前解決の途中で別のドメイン名を経由することがあっても、アプリケーションがその中間の名前を認証する手順を別途定めていない限り、中間の名前は参照識別子ではなく、参照識別子として扱ってはなりません(MUST NOT、§6.1.1)。RFCは、こうすることでDNSと名前解決が攻撃対象から外れると説明しています。名前解決の過程そのものはRFC 9525の範囲外です(§1.4.2)。仕組みについてはDNSの名前解決の記事を参照してください。
照合の流れは次のとおりです(§6、§6.2)。
- クライアントがソースドメイン(とサービス種別)から参照識別子のリストを作る。
- サーバーが証明書で提示識別子を送る。
- クライアントが参照識別子ごとに提示識別子と照合する。ひとつでも一致すれば成功で、その時点で探索を止めるべきです(SHOULD)。リストを使い切っても一致がなければ失敗です。
一致した場合、クライアントは一致した参照識別子をそのサービスの検証済みの識別情報として使わなければなりません(MUST、§6.6)。
HTTPSで使う識別子:DNS-IDとIP-ID
RFC 9525が扱う識別子は、すべて証明書のsubjectAltName(SAN)拡張に入ります(§1.5)。
| 識別子 | SANエントリの型 | 使われる場面 |
|---|---|---|
| DNS-ID | dNSName |
ドメイン名で接続するとき |
| IP-ID | iPAddress |
IPアドレスへ直接接続するとき |
| SRV-ID | otherName(SRVName) |
DNS SRVでサービスを探すプロトコル |
| URI-ID | uniformResourceIdentifier |
証明書にURIを使うと定めたプロトコル |
SRV-IDとURI-IDは「どのホストか」に加えて「どのサービスか」(たとえばIMAPやSIP)まで結び付ける識別子です。RFCはXMPPとSIPをその例に挙げています(§4.1)。一方でRFC 9525は、HTTPはサーバー証明書でのURIの使用を規定していないと書いており(§4.2)、通常のHTTPSではDNS-IDとIP-IDを考えれば足ります。
RFC自身が挙げる例は次のとおりです(§6.1.2)。
https://www.bigcompany.example/に接続するブラウザの参照識別子は、DNS-IDwww.bigcompany.exampleのひとつだけです。証明書のDNS-IDがweb.bigcompany.exampleなら拒否されます。https://192.0.2.107/に接続するとIP-ID192.0.2.107、https://[2001:db8::abcd]に接続するとIP-ID2001:db8::abcdがそれぞれ唯一の参照識別子です。
Common Nameは使わない
RFC 9525では、証明書のsubjectにあるCommon Name(CN)RDNをサービスの識別に使ってはなりません(MUST NOT、§2)。実質的に自由形式のテキストで型が厳密でなく、解釈があいまいになるためです。同じ理由で、subjectName内のほかのRDNも識別に使ってはなりません(MUST NOT)。
RFC 6125ではこれをCN-IDと呼んでいましたが、RFC 9525の変更点一覧(付録A)は、サーバーの識別情報はsubjectAltName拡張でのみ表現でき、commonNameを使うことはもはや有効ではないと明記しています。要約の節(§1.3)も「ドメイン名に見える文字列をCNに入れたり検査したりしない」とまとめています。
実務的に言い換えると(RFCの規則から導いた解釈)、ホスト名がCNにだけあり、SANに該当するDNS-IDがない証明書は、RFC 9525に従うクライアントでは名前一致の根拠になりません。
DNS名の照合と国際化ドメイン名
参照識別子のドメインが国際化ドメイン名(IDN)でない場合、ラベル単位で大文字小文字を区別しないASCII比較を行います(MUST、§6.3)。たとえばWWW.BigCompany.Exampleは比較のためにwww.bigcompany.exampleへ小文字化されます。後述のワイルドカード規則を除き、すべてのラベルが一致する必要があります。
国際化ドメイン名には次の規則があります。
- DNS-IDにはUS-ASCIIの範囲外の文字を使えず、国際化ラベルはA-label(
xn--で始まるASCII形式)で表します(§2)。 - 参照識別子にU-label(Unicode形式のラベル)があれば、クライアントは比較前にA-labelへ変換しなければならず(MUST)、A-label同士は大文字小文字を区別しないASCIIで比較します(MUST、§6.3)。
- 照合はA-labelのみで行います。見た目の似た文字による混乱などの表示上の問題は、証明書の照合ではなくアプリケーションプロトコルとユーザーインターフェースが扱う問題だとRFCは線を引いています(§7.3)。
A-labelとU-labelの変換はPunycodeと国際化ドメイン名の記事で詳しく扱っています。
もうひとつ、RFC 9525が対象とするソースドメインはFQDNです。完全修飾でない名前の使用は範囲外で、予期しない、または未定義の動作につながる可能性があると書かれています(§1.5)。
ワイルドカードの規則
RFC 9525ではワイルドカードは証明書の既定の機能として扱われますが(§1.3)、プロトコル仕様がワイルドカードを禁止することもできます(§3)。ワイルドカードをサポートする場合、提示識別子の*は次の条件を両方満たす必要があります(§6.3)。
- ワイルドカード文字はひとつだけである。
- ワイルドカード文字は最も左のラベルの内容全体としてのみ現れる。
条件を満たさない提示識別子は無効で、無視しなければなりません(MUST)。また、ワイルドカードは参照識別子のラベル1つにしか一致しません。RFCは、これが1つ以上のラベルに一致しうるDNSのワイルドカードとは異なる規則だと明記しています。
RFC本文にある例は、*.bigcompany.exampleは許されるが*.*.bigcompany.exampleは許されない、というものです(§7.1)。下の表のほかの行は、規則を当てはめてこの記事で作った例です。
| 証明書のDNS-ID | 接続先の名前 | 結果(規則から導いた例) |
|---|---|---|
*.bigcompany.example |
www.bigcompany.example |
一致:*がラベル1つ(www)に対応 |
*.bigcompany.example |
a.b.bigcompany.example |
不一致:ワイルドカードはラベル2つに対応しない |
*.bigcompany.example |
bigcompany.example |
不一致:*に対応するラベルがない |
w*.bigcompany.example |
www.bigcompany.example |
無視:*がラベル全体ではない |
www.*.example |
www.bigcompany.example |
無視:*が最も左のラベルにない |
*.*.bigcompany.example |
a.b.bigcompany.example |
無視:ワイルドカードが2つ(RFCの例) |
*.co.ukや*.comのようにパブリックサフィックスを覆うワイルドカードを防ぐことは、RFC 9525の範囲外です(§7.1)。ワイルドカード証明書はそのドメイン配下の単一ラベルのホストすべてを保証するため、意図しないホストや問題のあるホストまで保証してしまうリスクがあることもRFCは指摘しています。
IPアドレスへ直接接続する場合
URLにIPアドレスを直接書くと、参照識別子はIP-IDになります(§6.1.1)。規則は短く、厳格です。
- IP-IDの参照識別子は、SANの
iPAddressエントリの値と正確に一致しなければならず、ネットワーク単位のような部分一致はありません(MUST、§6.2)。 - 比較は参照識別子のバイトと
iPAddressエントリのバイトをオクテット単位で突き合わせる方式です(§6.4)。IPv4は4オクテット、IPv6は16オクテットで、テキスト表記からこの値へ変換が必要な場合があります(§2)。 - DNS問い合わせの結果として得たIPアドレスは間接(indirect)識別子で、間接的なIP-IDの使用はRFC 9525の範囲外です(§2)。
RFC 9525は逆引きDNSに直接は触れていません。ただし、IPアドレスが参照識別子であればそれはIP-IDであり(§6.1.1)、DNS-IDの参照識別子は、入力に含まれるか入力から安全に導かれたFQDN、またはユーザー設定でソースドメインに明示的に結び付けられたFQDNから作ると定めています。したがって(この記事の解釈)、IPで接続しておきながら問い合わせで得たホスト名を証明書のDNS-IDと照合するやり方は、RFC 9525が定める手順ではありません。
IP接続には運用上の注意点もあります。TLSのSNI拡張はドメイン名しか運べないため、IP-IDを参照識別子とするクライアントは接続時にその情報をサーバーへ伝えられません。そのため、IP-IDを提示したいサーバーはSNIなしの接続に対してその証明書を提示する必要があります(§7.4)。
また、IPv4アドレスのテキスト表記は有効なDNS名でもあります(§3)。システムのある部分が値をIPアドレスとして、別の部分がFQDNとして分類すると、セキュリティ規則がその間で抜け落ちることがあるため、RFCは識別子の分類を一貫させるよう求めています(§7.4)。§3は、URI仕様と同様にまず有効なIPv4アドレスかどうかを判定する方法を例に挙げています。
一致しなかったときの扱い
一致する提示識別子が見つからなかったときの動作は、クライアントの種類によって異なります(§6.6)。要求レベル(MUST/SHOULD/MAY)をそのまま示します。
自動化されたアプリケーション
- bad certificateエラーで通信の試みを終了し、エラーを適切に記録すべきです(SHOULD)。
- この動作を無効にする設定を用意してもよいですが(MAY)、既定で無効にしてはなりません(MUST NOT)。
人が直接操作するクライアント
- ユーザーに識別情報の不一致を知らせ、bad certificateエラーで通信の試みを自動的に終了すべきです(SHOULD)。
- 上級ユーザーに不一致を承知で続行する選択肢を与えてもかまいません(MAY)。RFCはこの場合きわめて慎重に扱う必要があるとし、まず中止を勧め、それでも続行するなら証明書パス全体を確認させる方法を例に挙げています。
- 提示された証明書を以後の接続でも有効として受け入れる機能を提供してもかまいません(MAY)。ただし、このような場当たり的な「ピン留め(pinning)」が以後の接続をその証明書だけに制限すべきではなく(SHOULD NOT)、特定の相手に特定の証明書を静的に強制するポリシーは、失敗した接続の場でのその場しのぎの例外ではなく、事前設定としてのみ提供すべきです(SHOULD)。
まとめると、接続の終了はRFC 9525ではSHOULDレベルの既定動作であり、検査を既定で無効にしないことは自動化クライアントに対するMUST NOTです。
実装・設定チェックリスト
以下はRFC 9525の規則を実務上の確認項目に置き換えたものです。特定のライブラリやツールでの扱い方は、それぞれの公式ドキュメントを確認してください。
クライアントを実装・設定するとき
- 参照識別子はURLや設定などクライアント側の入力から作り、証明書の内容からは作らない(§6.1.1)。
- DNS名前解決の途中で経由した中間の名前を参照識別子として使わない(§6.1.1)。
- 名前の検査でCNへフォールバックしない(§2)。
- DNS名はラベル単位で大文字小文字を区別しないASCII比較とし、IDNはA-labelへ変換してから比較する(§6.3)。
- ワイルドカードは唯一の
*で、かつ最も左のラベル全体である場合にのみ認め、ラベル1つにだけ一致させる(§6.3)。 - IPで接続する場合は、SANの
iPAddressとオクテット単位で正確に比較する(§6.2、§6.4)。 - IPアドレスとドメイン名の分類をシステム全体で一貫させる(§3、§7.4)。
- 自動化クライアントは不一致時に既定で接続を切り、記録する。検査を無効にするオプションがあるなら既定値は有効にする(§6.6)。
- 名前の検査とは別に、証明書パス、有効期限、失効の検査が行われているか確認する(§1.2、§6)。
証明書を申請する・サーバーを設定するとき
- クライアントが接続に使うホスト名がSANの
dNSNameとして入っているか確認する。CNだけでは不十分(§2、付録A)。 -
*.bigcompany.exampleひとつでbigcompany.exampleや複数階層下の名前まで覆えると考えない(§6.3、上の表の導出例)。 - 国際化ドメイン名はA-label形式で入れる(§2)。
- IPアドレスでの接続を受けるなら、そのアドレスを
iPAddressエントリとして入れ、SNIなしの接続でその証明書が提示されるか確認する(§4.2、§7.4)。 - 1つのサービスを識別するのに必要なだけの名前を入れる。証明書の名前の集合のうち最も弱いサーバーが全体の強度を決める(§5、§7.5)。
名前の一致が保証しないこと
名前の照合に成功しても、それだけで接続が安全だとは言えません。RFC 9525は自らの範囲を次のように定めています。
- RFC 9525はPKIX(RFC 5280)の発行・検証規則を置き換えません。証明書の構文、名前制約や拡張鍵用途などの拡張、証明書パスの処理はPKIXの領分です(§1.2)。
- 扱うのは末端(end entity)サーバー証明書の名前だけで、チェーンの構築や有効性の検査は行いません。適切に認証するには、アプリケーションが証明書パス全体を検証する必要があります(§1.2)。
- 有効期限や失効のような追加の検査も必要ですが、サービスの識別情報の検証ではないため、その方法は範囲外です(§6)。
- クライアントが信頼するCAが発行した証明書はすべて信頼するという前提に立っており、悪意あるサーバーやバグのあるアプリケーションへの追加検査はアプリケーションプロトコルやクライアントの責任です(§7.7)。
- 入力そのものが不正なら(たとえばフィッシングのリンクをクリックした場合)、名前の検証に成功しても意図しないサービスと通信することになりえます(§6.1.1)。
- RFCは、引用しているワイルドカード関連の攻撃が最初の平文HTTP接続の乗っ取りに依存していると述べています(§7.1)。最初の接続をHTTPSにする問題は名前の照合とは別で、HSTSの記事で扱っています。
参考資料
以下の公式資料は2026-10-18に確認しました。
- RFC 9525「Service Identity in TLS」(テキスト版): https://www.rfc-editor.org/rfc/rfc9525.txt
- RFC 9525 情報ページ(RFC Editor): https://www.rfc-editor.org/info/rfc9525