デジタル証明書

【図解】SANsとSNIの違い ~サブジェクト代替名とコモンネーム,ワイルドカードの使い方やTLSパケットキャプチャ~

デジタル証明書の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 パケット内にセットされる属性です。

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

SNI の役割と使い方

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

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

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

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

コメント

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