06.SSL設定(1) … SSLの概要


◆ "SSL"(Secure Socket Layer)とは、クライアントからサーバーに接続する際に、まず、そのサーバーの「身元」を「サーバー証明書」を用いて検証し、身元が確認できれば、次に、通信内容を暗号化する為の「鍵」をクライアントとサーバー間で交換し、以降の通信はその鍵を使って全ての通信を暗号化した状態で行う仕組みを言う。

◆ SSLの仕組みは、以下に示す複数の既存技術を組み合わせることで実現されている。

(1) 共通鍵暗号化方式

「共通鍵暗号化方式」は「暗号化」と「復号化」に同じ「共通鍵」を用いる暗号化通信方式で、データを送る側と受け取る側で同じ鍵を使ってデータの暗号化と復号化を行う。

共通鍵暗号化方式は、処理負荷が軽い反面、暗号化と復号化に同じ鍵を使うので、その鍵が第三者に知られてしまうと簡単に暗号化が解除出来てしまうという弱点を持つ。そのため通信者間で安全に(第三者に漏れないように)鍵を受け渡しする手段を別途考えて用意する必要があるが、しかし、そもそも通信者間で安全に鍵を受け渡しできるような手段があるのであれば、その手段を使ってデータそのものを相手に渡せば良いという根本的な矛盾を抱えている。

SSLにおいては、メインの通信にこの共通鍵暗号化方式が使われるが、鍵の安全な受け渡しについては、別途「公開鍵暗号化方式」を用いて行うことで、共通鍵暗号化方式の弱点をカバーしている。共通鍵はクライアント側でSSLのセッション毎に新たなものが生成され、それを公開鍵暗号化方式を用いて暗号化した状態でサーバーに送る事で安全な鍵の受け渡しを実現している。

(2) 公開鍵暗号化方式

「公開鍵暗号化方式」 = "PKI"(Public Key Infrastructure)は、「暗号化」と「復号化」に異なる鍵を用いる暗号化通信方式で、基本的には「公開鍵」で暗号化して「秘密鍵」で復号化する手順をとる。

「秘密鍵」と「公開鍵」の「鍵ペア」はデータを受信する側が生成し、その内の一方の「公開鍵」をデータを送信する側に送る。データを送信する側は、受け取った公開鍵を使ってデータを暗号化して受信する側に送る。その「公開鍵で暗号化されたデータ」を受け取った受信側は、それを自身の「秘密鍵」で復号化して元のデータを得る。

 
     <受信する側>       <送信する側>
┏━━━━━━━━━━━━━┓ ┏━━━━━━━━━━┓
┃             ┃ ┃    ┌───┐ ┃
┃ 鍵ペア生成       ┃ ┃    │データ│ ┃
┃   ↓         ┃ ┃    └───┘ ┃
┃ ┌───┐       ┃ ┃┌───┐ ↓   ┃
┃ │公開鍵│─────────→│公開鍵│→◎暗号化┃
┃ ├───┤       ┃ ┃└───┘ ↓   ┃
┃ │秘密鍵│       ┃ ┃  ┌──────┐┃
┃ └───┘       ┃ ┃  │暗号化データ│┃
┃   ↓ ┌──────┐┃ ┃  └──────┘┃
┃復号化◎←│暗号化データ│←────────┘   ┃
┃   ↓ └──────┘┃ ┃          ┃
┃ ┌───┐       ┃ ┃          ┃
┃ │データ│       ┃ ┃          ┃
┃ └───┘       ┃ ┃          ┃
┗━━━━━━━━━━━━━┛ ┗━━━━━━━━━━┛
 

復号化に用いる「秘密鍵」を外部に晒す必要がなく、また、暗号化に用いる「公開鍵」についても、それで暗号化したデータはもう一方の「秘密鍵」でしか復号できないので、公開鍵がだれの手に渡ったとしても安全上の問題はなく、「共通鍵暗号化方式」のように安全な鍵の受け渡しに腐心する必要がない。

しかし、その反面、暗号化の仕組みが複雑な為に処理負荷が非常に高いという弱点がある。

SSLにおいては、通信開始時のサーバーからクライアントへの「サーバー証明書」の送付に、この公開鍵暗号化方式の手順の一部が使われている。サーバーからクライアントへサーバーの公開鍵を送付する際に、公開鍵をそれ単体で送るのではなく、その公開鍵を内包した「サーバー証明書」を送付することで、公開鍵の送付とサーバー証明書の送付を同時に行っている。

また、SSLにおいては、メインの通信には、処理負荷が高いこの公開鍵暗号化方式ではなく、処理負荷が軽い共通鍵暗号化方式が用いられるが、共通鍵暗号化方式の「安全な鍵の受け渡し」という弱点をカバーする為に、この公開鍵暗号化方式が用いられている。共通鍵はクライアント側で生成され、それをサーバーに送る際に、SSLの通信開始時にサーバーから「サーバー証明書」に内包される形で送られてきた「公開鍵」を使って共通鍵を暗号化してサーバーに送ることで安全な鍵の受け渡しを実現している。

(3) 電子署名(デジタル署名)

公開鍵暗号化方式では基本的には「公開鍵」で暗号化して「秘密鍵」で復号化するが、その逆に「秘密鍵」で暗号化して「公開鍵」で復号化することも可能になっている。

だれでも入手可能な「公開鍵」で暗号化が解除できてしまうこの仕組みは、一見すると何の利用価値も無い様に思えてしまうが、しかし、暗号化に用いた「秘密鍵」の持ち主が「世界で只一人しか存在しない」という事実を利用すると、秘密鍵の持ち主がデータを送信する際に、その送り主が確実に自分であるという事を、データを受信する側に対して保証することができるようになる。

「電子署名(デジタル署名)」とは、この仕組みを応用したもので、具体的には、秘密鍵の持ち主がデータを送信する際に、送るデータのハッシュ値を計算してそれを秘密鍵で暗号化し、それをデータの本体に添付して相手に送り、データを受け取った側は、受け取ったデータに添付された「暗号化されたハッシュ値」を同じ秘密鍵の持ち主から受け取った「公開鍵」で復号化を試みて、それでハッシュ値の復号化に成功すれば、まず、そのデータの送り主は確実にその公開鍵とペアの秘密鍵の持ち主であるという確証が得られるとともに、更に、データを受け取った側でデータ本体のハッシュ値を再度計算して、その値が先の復号化して得られたハッシュ値と一致すれば、途中でデータの改竄が行われていないという確証も同時に得られる事になる。

データのハッシュ値は「メッセージダイジェスト」とも呼ばれ、そのメッセージダイジェストを秘密鍵で暗号化したものが、即ち「電子署名」ということになる。

 
    <送信側>                     <受信側>
  ┌───────┐                 ┌───────┐
  │  データ  │                 │  データ  │
  │       │──┐           ┌─→│       │
  └───────┘  │           │  └───────┘
      ↓      │           │      ↓
      ◎ハッシュ計算│ ┌───────┐ │      ◎ハッシュ計算
      ↓      └→│  データ  │─┘      ↓
  ┌───────┐    │       │    ┌───────┐
  │ メッセージ │    ├───────┤    │ メッセージ │
  │ ダイジェスト │    │  電子署名  │    │ ダイジェスト │
  └───────┘  ┌→│       │─┐  └───────┘
┌───┐ ↓      │ └───────┘ │      ↓
│秘密鍵│→◎暗号化   │           │    比較◎
└───┘ ↓      │           │      ↑
  ┌───────┐  │           │  ┌───────┐
  │  電子署名  │──┘           │  │ メッセージ │
  │       │              │  │ ダイジェスト │
  └───────┘              │  └───────┘
                         │┌───┐ ↑
                         ││公開鍵│→◎復号化
                         │└───┘ ↑
                         │  ┌───────┐
                         └─→│  電子署名  │
                            │       │
                            └───────┘
 

SSLにおいては、通信開始時に公開鍵暗号化方式の手順でサーバーからクライアントへサーバーの公開鍵が送付されるが、それは公開鍵単体で送られるのではなく、サーバーの公開鍵を内包した「サーバー証明書」を送付することにより行われる。「サーバー証明書」にはこのデジタル署名が施されており、それによって、クライアントに対して、そのサーバー証明書の送り主が、そのサーバー証明書を認証したCA局である事を確実に保証すると同時に途中で改竄されていない事を保証している。

(4) サーバー証明書

「サーバー証明書」とは、文字通りサーバーの身元を証明する為のもので、その実体は、そのサーバーの「公開鍵」と、そのサーバーの所在地や管理者に関する情報、証明書としての有効期間、ならびに、この証明書を認証した認証機関の名称などの情報から構成されている。

サーバー証明書は、ただ生成しただけでは証明書としての効力は無く、必ず何がしかの認証機関(ベリサイン社などが有名)の認証を受ける必要がある。

認証機関はCA(Certificate Authority)局とも呼ばれ、CA局もまた独自の「秘密鍵」と「公開鍵」とを保有している。

CA局で認証を受けるとは、具体的には、CA局で「電子署名」してもらうことを意味する。即ち、そのサーバー証明書のハッシュ値を計算して「メッセージダイジェスト」を生成し、それをCA局の秘密鍵で暗号化した「電子署名」を生成してもらうことになる。

 
  <サーバー証明書>         <CA局α>
┏━━━━━━━━━━━┓┐┏━━━━━━━━━━━━━━━┓
┃発行先:foobar.dip.jp ┃│┃               ┃
┃発行者:CA局α    ┃│┃               ┃
┃───────────┃│┃ハッシュ計算┌───────┐┃
┃foobar.dip.jpの公開鍵 ┃├──→◎──→│ メッセージ │┃
┃───────────┃│┃      │ ダイジェスト │┃
┃有効期間 XXXX 〜 XXXX ┃│┃      └───────┘┃
┃───────────┃│┃┌───────┐ ↓    ┃
┃     :     ┃│┃│CA局αの秘密鍵│→◎暗号化 ┃
┣━━━━━━━━━━━┫┘┃└───────┘ │    ┃
┃  CA局αの電子署名  ┃←───────────┘    ┃
┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━┛
 

CA局自身も自分の身元を証明するための証明書(認証局証明書)を発行しており、その内容は、サーバー証明書と同様に、そのCA局の「公開鍵」や、証明書としての有効期間、ならびに、そのCA局が中間の認証機関で、より上位の認証機関による認証を受けたものである場合には、その認証機関の名称などの情報から構成されている。

つまり証明書は階層構造を形成しており、サーバー証明書はその最下層に位置し、その上位にそのサーバー証明書を認証した中間CA局の証明書が位置し、さらにその上位にその中間CA局を認証したより上位のCA局の証明書が位置する…といった具合に連鎖している。

この証明書の「連鎖」のことを「証明書チェーン」とよび、その証明書チェーンの終点(頂点)に位置する証明書を、「根幹」を意味する「ルート」("root")という単語を付して「ルート証明書」と呼んでいる。

「ベリサイン社」などの主要なCA局が発行する認証局証明書は、基本的には予めPCにインストールされており、サーバーから受け取ったサーバー証明書を「検証する」とは、具体的には、受け取ったサーバー証明書を起点として、「証明書チェーン」を順次辿り、最終的に「ルート証明書」に辿り着くことができれば検証は完結し「合格」となる。

 
  <サーバー証明書>     <中間認証局証明書>     <ルート証明書>
┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━┓
┃発行先:foobar.dip.jp ┃┌→発行先:中間CA局β  ┃┌→発行先:CA局α┬同じ ┃
┃発行者:中間CA局β───┘┃発行者:CA局α─────┘┃発行者:CA局α┘   ┃
┃───────────┃ ┃───────────┃ ┃───────────┃
┃foobar.dip.jpの公開鍵 ┃┌─中間CA局βの公開鍵  ┃┌─CA局αの公開鍵─────┐
┃───────────┃│┃───────────┃│┃───────────┃│
┃有効期間 XXXX 〜 XXXX ┃│┃有効期間 XXXX 〜 XXXX ┃│┃有効期間 XXXX 〜 XXXX ┃│
┃───────────┃│┃───────────┃│┃───────────┃│
┃     :     ┃│┃     :     ┃│┃     :     ┃│
┣━━━━━━━━━━━┫│┣━━━━━━━━━━━┫│┣━━━━━━━━━━━┫│
┃ 中間CA局βの電子署名 ┃│┃  CA局αの電子署名  ┃│┃  CA局αの電子署名  ┃│
┗━━━━━━━━━━━┛│┗━━━━━━━━━━━┛│┗━━━━━━━━━━━┛│
      ↑  復号化  │      ↑  復号化  │      ↑  復号化  │
      └──────┘      └──────┘      └──────┘
 
└─ サーバーから受信 ─┘ └──── クライアントPCにインストール済み ────┘
 

上の図を例に、サーバー証明書の検証処理の流れを解説すると、以下のようになる。

@ まず、サーバー「foobar.dip.jp」から受け取ったサーバー証明書の「発行先」欄の値="foobar.dip.jp"を参照し、それがブラウザのアドレス欄に入力されたURL="https://foobar.dip.jp"のFQDN部分(完全修飾ドメイン名)と一致してるかを確認する。一致しなければ、ユーザーが意図しないサーバーに接続されたと判断してブラウザ画面に警告を表示して検証を終了する。

A 一致した場合は、続けて、そのサーバー証明書を認証した認証局を調べるためにサーバー証明書の「発行者」欄を参照し、その名称が「中間CA局β」であることを知る。続けて、その名称を手掛かりとして、予めPCにインストールされているCA局証明書の中で、その「発行先」欄の名称が「中間CA局β」となっているものを探す。該当するCA局証明書が見つからなければ、そのサーバー証明書はCA局で認証されてない不正な証明書と見なしてブラウザ画面に警告を表示して検証を終了する。

B 「中間CA局β」のCA局証明書が見つかった場合は、その中に含まれる「中間CA局βの公開鍵」で、サーバー証明書の「電子署名」の復号化を試みる。復号化できなかった場合は、そのサーバー証明書は不正な証明書と見なしてブラウザ画面に警告を表示して検証を終了する。

C 「電子署名」の復号化に成功した場合は、そのサーバー証明書は確実にその「中間CA局β」が認証(電子署名)したものだと断定できる。続けて、改竄の有無をチェックする為にサーバー証明書のハッシュ値を計算してメッセージダイジェストを生成し、その値と、先に電子署名を復号化して得られたメッセージダイジェスト(=ハッシュ値)とを比較する。そこでもしもメッセージダイジェスト(ハッシュ値)が一致しなければ、受け取ったサーバー証明書は途中で何らかの改竄を受けたと判断し、ブラウザ画面に警告を表示して検証を終了する。

D メッセージダイジェスト(ハッシュ値)が一致すれば、そのサーバー証明書は改竄を受けていない正式なものと断定できる。続けて、今度は、「中間CA局β」の証明書の検証を行う。先のサーバー証明書の検証と同様に、その「中間CA局β」の証明書を認証したより上位の認証局を調べる為に「中間CA局β」の証明書の「発行者」欄を参照して、その名称が「CA局α」であることを知る。続けて、その名称を手掛かりとして、予めPCにインストールされているCA局証明書の中で、その「発行先」欄の名称が「CA局α」となっているものを探す。該当するCA局証明書が見つからなければ、その「中間CA局β」の証明書は不正な証明書と見なしてブラウザ画面に警告を表示して検証を終了する。

E 「CA局α」の証明書が見つかった場合は、その中に含まれる「CA局αの公開鍵」で、「中間CA局β」の証明書の「電子署名」の復号化を試みる。復号化できなかった場合は、その「中間CA局β」の証明書は不正な証明書と見なしてブラウザ画面に警告を表示して検証を終了する。

F 「電子署名」の復号化に成功した場合は、その「中間CA局β」の証明書は確実にその「CA局α」が認証(電子署名)したものだと断定できる。続けて改竄の有無をチェックする為に「中間CA局β」の証明書のハッシュ値を計算してメッセージダイジェストを生成し、その値と、先に電子署名を復号化して得られたメッセージダイジェスト(=ハッシュ値)とを比較する。そこでもしもメッセージダイジェスト(ハッシュ値)が一致しなければ、その「中間CA局β」の証明書は何らかの改竄を受けていると判断し、ブラウザ画面に警告を表示して検証を終了する。

G メッセージダイジェスト(ハッシュ値)が一致すれば、その「中間CA局β」の証明書は改竄を受けていない正式なものと断定できる。続けて、同様に、「CA局α」の証明書の検証を行う。「CA局α」の証明書の「発行者」欄の値は「発行先」欄の値と同じなので、この証明書は「ルート証明書」だと判断できる。ルート証明書は、そのCA局が自分自身で認証(自己署名)したものなので、それに添付される「電子署名」は、自身の証明書に含まれる「CA局αの公開鍵」で復号化できるはずである。ここでもしも復号化できなかった場合は、その「CA局α」のルート証明書は不正な証明書と見なしてブラウザ画面に警告を表示して検証を終了する。

H 「電子署名」の復号化に成功した場合は、その「CA局α」のルート証明書は確実に「CA局α」自身が認証(自己署名)したものだと断定できる。続けて改竄の有無をチェックする為に「CA局α」のルート証明書のハッシュ値を計算しメッセージダイジェストを生成し、その値と、先に電子署名を復号化して得られたメッセージダイジェスト(=ハッシュ値)とを比較する。そこでもしもメッセージダイジェスト(ハッシュ値)が一致しなければ、その「CA局α」のルート証明書は何らかの改竄を受けていると判断し、ブラウザ画面に警告を表示して検証を終了する。

I メッセージダイジェスト(ハッシュ値)が一致すれば、その「CA局α」のルート証明書は改竄を受けていない正式なものと断定でき、よって、遡って起点となるサーバー「foobar.dip.jp」のサーバー証明書も正式なもの結論付ける事が出来る。


補足 … 本資料で構築するシステムで使用する証明書について。

本資料でシステム構築時に自分用に生成する証明書は、自分で生成した証明書を自分で認証(自己署名)するので、それは「ルート証明書」となる。それをクライアントPCにインストールして使用するとともに、サーバーに対しても、その同じものを「サーバー証明書」として組み込み込んで使用する。


◆ SSLの処理の流れを、前出の「システム構成図(例)」を例に説明すると、大体以下のようになる。

(0) まず、システム管理者が事前に行っておく準備作業(システムセットアップ時の作業)として、サーバーの「秘密鍵」とサーバーの公開鍵を含む「サーバー証明書」を生成し、Webサーバーに組み込む作業を行う。その作業の大まかな流れは以下の通り。

1. まず最初に「秘密鍵」を生成する。

2. 次に、その秘密鍵とペアになる「公開鍵」を含む「サーバー証明書」を生成する(公開鍵はサーバー証明書を構成する項目の一項目として証明書の生成時に共に生成される)。

正確には、ここで生成するデータは、CA局に認証(電子署名)を要求する為のデータで、これを「証明書署名要求」("CSR"…"Certificate Signing Request")と呼ぶ。

3. サーバー証明書(証明書署名要求)を公的CA局に提出して認証(電子署名)を受ける。 (※ 本資料の作業では自身で認証を行う。)

4. 「秘密鍵」と認証を受けた「サーバー証明書」とをWebサーバーに組み込む(FA)。

5. (※ 本資料でのみ行う作業) サーバー証明書を「ルート証明書」として(*1)、クライアントPCにインストールする(BC)。

*1 サーバー証明書を自分で認証した場合はそれ自体が「ルート証明書」となる。また、もしも、独自のCA局を構築して、それを使って認証した場合は、その「独自のCA局」のCA局証明書を「ルート証明書」としてインストールする事になる。

(1) サーバーにSSLで接続する為に、クライアントPCのWebブラウザのアドレス欄@に、スキーム名が"https://"で始まるURLを入力する。

(2) クライアントのSSL接続要求はサーバーのTCP-443番ポートに届き、それを受け取ったサーバーは、自身の「公開鍵」を含んだ、自身の身分を証明する「サーバー証明書」Aをクライアントに対して送信する。

(3) サーバーから「サーバー証明書」を受け取ったクライアントPCのWebブラウザは、まず、その「サーバー証明書」が正式なものかどうかを、PCに予めインストールされている「認証局のルート証明書」を参照して検証する(*2)。

*2 本資料の作業では「サーバー証明書」を自分で認証してそれを「ルート証明書」としてWebブラウザにインストール(BC)し、それと照合させることで検証を行わせる。

(4) 「サーバー証明書」の検証結果が不合格だった場合は、ここでクライアントPCのWebブラウザに警告メッセージが表示される(*3)。

*3 この警告画面において、警告を無視して接続するような操作は、絶対にしてはならない。また、ルート証明書が正しくインストールされていて、その有効期間も切れていないにも係わらず、この警告が表示されたような場合は、何らかの中間者攻撃("MITM"攻撃)を受けている可能性がある。よって、この場合も、警告を無視して接続するような操作は絶対にしてはならない

(5) 「サーバー証明書」が検証に合格した場合は、クライアントPCのWebブラウザにおいて「共通鍵」Dが生成される。

(6) クライアントPCのWebブラウザにおいて生成された「共通鍵」Dは、サーバーから受け取った「サーバー証明書」に含まれる「公開鍵」Eで暗号化されてサーバーに送信される。

(7) 暗号化された共通鍵を受け取ったサーバーは、それを自身の「秘密鍵」Fで復号化して「共通鍵」Gを取得する。

(8) 以降の通信は、サーバー・クライアントとも、この「共通鍵」DGを使って暗号化通信を行う。