デジタル証明書

【図解】SANs(サブジェクト代替名)とSNI(server_name indication),ワイルドカードの違い

SNI と SANs の違い

SNI は TLS ネゴシエーションの中の最初のパケット ClientHello の中に含まれる extension (拡張属性) です。これは主に、1台のサーバ内に複数のドメインを持つ https サーバに対し、クライアントが「どの URL のサイトへ https アクセスしようとしているか」を提示し、適切なサーバ証明書を引き出すために TLS 規格に追加された属性です。

もともとの目的は上記の通りですが、最近では Web フィルタプロキシや UTM などではこの SNI により宛先の URL を認知し、その URL が危険なサイトではないかどうかを検査しています。なのでセキュリティ上でとても重要な役割を担っています。(昔はデジタル証明書のコモンネームや SANs を検査する方式だった。)

一方、SANs は 1 つの証明書で複数の URL をカバーするために作られた、X.509 規格に追加された拡張フィールドです。

つまり、SNI は TLS 通信上の拡張属性、SANs は X.509 規格で示されたデジタル証明書のファイルデータ構造上の拡張フィールドになります。目的も前述の通りに異なります。

SANs (サブジェクト代替名, サブジェクトの別名) とコモンネーム

デジタル証明書 (サーバ証明書, SSL 証明書) では暗号化だけでなく認証も行うことができます。

例えば Web サーバにデジタル証明書をセットし、https を使うようにする場合、パケットの暗号化だけでなく、「その Web サーバが本当に正しいものか?偽装サイトではないのか?」といった認証を行います。

なのでデジタル証明書は正しく作成しないと、クライアントから https 等のアクセスをする際にエラーが表示されてしまいます。

Web サーバの正しさを証明するためにいくつか観点があるのですが、その観点のうちの 1 つが、「証明書が示すホスト名 (FQDN)」と「ユーザがブラウザに入力したホスト名 (FQDN)」が一致するかどうか?というものです。

証明書が示すホスト名は、証明書にあるサブジェクト属性の中にある「コモンネーム」が知られていますが、最近では SANs (サブジェクト代替名) を使うのが主流です。「サブジェクトの別名」と呼ぶこともあります。

以下は 本サイトの証明書の例です。赤枠がサブジェクトの CN (Common Name) であり、青枠がサブジェクト代替名です。

IE (Internet Explorer) ではコモンネームとサブジェクト代替名の両方を見ているようですが、最近では Chrome は「サブジェクト属性は無視する(つまりその中にあるコモンネームは見ない)、SANs のみで確認を行う」と宣言しています

Chrome Deprecates Subject CN Matching
If you’re using a Self-Signed certificate for your HTTPS server, a deprecation coming to Chrome may affect your workflow. Chrome 58 will require that certificat...

Chrome 58 will require that certificates specify the hostname(s) to which they apply in the SubjectAltName field; values in the Subject field will be ignored.

実際、SANs に FQDN を含んでいない場合は、例えコモンネームに値が入っていても Chrome では「NET::ERR_CERT_COMMON_NAME_INVALID」のエラーが表示されます。(IE ではエラーになりませんが、Edge は Chrome ベースなのでやはりエラーになります。)

SANs (Subject Alternative Names)

SANs とは本来的には「サブジェクト≒コモンネーム」の代わりとなる名前であり、コモンネームとは別に、URL として使うことを許された名前のことなのですが、前述の通り、今では偽装サイトか否かのチェックは SANs のほうがメインで使われます。

例えば Yahoo!JAPAN (https://yahoo.co.jp/) の証明書を見てみましょう。(Chrome の URL 左横の鍵マークをクリックし、「証明書」をクリックし、ポップアップした証明書の「詳細」タブをクリックすると、以下の画面が表示されます。)

サブジェクト代替名に yahoo.co.jp が含まれていることが確認できます。

サブジェクト代替名は、その Web サーバが複数の FQDN URL を持つ場合やテスト用に URL を変更する場合などに使われます。

ワイルドカード

ワイルドカードを使うと、その表現に合致した URL を持つ複数のサーバに使い回すことができます。

先程の Yahoo JAPAN の証明書ですが、サブジェクト代替名の上の方に *.yahoo.co.jp 等の * (アスタリスク) で始まるものがたくさんあります。

このアスタリスクは「ワイルドカード」と呼ばれ、任意の文字列と解釈されます。

なので例えば www.yahoo.co.jp といったサブドメインサイトであっても、この証明書を使えば「正しい URL」と解釈されます。

ワイルドカード証明書は『.yahoo.co.jp』で終わる FQDN ホスト名 (例えば www2.yahoo.co.jp や mail.yahoo.co.jp 等) のサーバであればどれにでも利用可能です。なので秘密鍵とセットでコピーして使いまわしができます。

SNI (Server Name Indication)

SANs と SNI の違い

SANs (サブジェクト代替名) はサーバ側にセットする証明書へ設定する内容でしたが、SNI (server_name indication) はクライアントが TLS によるネゴシエーションを開始する Client Hello パケット内にセットされる extension (拡張属性) です。

つまり SANs は「証明書に関するサーバ側の話」であり、SNI は「TLS に関するクライアント側の話」になります。

SNI の役割と使い方

バーチャルドメインを使って 1 つの IP アドレスで複数の https サイトを運用しているケースでは、クライアントからの https アクセス時に『どのサイトへアクセスしようとしているのか』という情報が無いと、サーバー側はどのサーバー証明書を提示して良いか分かりません。

SNI とは、クライアントが TLS セッション開始時の "Client Hello" メッセージにおいて "server_name indication" Extension を使ってサイト名をサーバに知らせる方法のことです。

以下に、このサイト(https://milestone-of-se.nesuke.com) にアクセスした際の Client Hello のパケットキャプチャを示します。

Extension: server_name の "Server Name" に本サイトの URL が示されていることが分かります。サーバー側はこの情報を見て、TLS Certificate において、どの証明書を提示するかを判断することができます。

コメント

タイトルとURLをコピーしました