ゼロからわかる SSL/TLS の解説を試みる

## TL; DR

- 公開鍵基盤と SSL/TLS
- 盗聴防止（共通鍵暗号方式、公開鍵暗号方式、ハイブリッド暗号方式）
- 改竄検知（メッセージ認証符号）
- なりすまし防止（認証局、デジタル署名、証明書、証明書チェーン）

## 公開鍵基盤と SSL/TLS

通信には様々な脅威が存在し、代表的なものとして **「盗聴」** **「改竄」** **「なりすまし」** が挙げられます。

「盗聴」とは通信経路に流れるデータを盗み見ること、「改竄」とは通信経路に流れるデータを書き換えてしまうこと、そして「なりすまし」とは通信相手が意図した相手であるかのように振る舞い、データを不正に受け取ることです。

![threat.png](https://qiita-image-store.s3.amazonaws.com/0/288168/70b39266-d69d-e00f-ef1e-f58470d39e89.png)

これらの脅威に立ち向かうための仕組みとして、 **公開鍵基盤 (Public Key Infrastracture, PKI)** というものがあります。PKI とは、 **公開鍵暗号方式** をいくつかの方法で応用することで **「盗聴されない」** **「改竄されても気付くことができる」** **「なりすましされても気付くことができる」** 通信を保証する仕組みです。そして **PKI を技術基盤としてセキュアな通信を実現するプロトコル** のことを **TLS/SSL** といいます。

以下では「盗聴防止」「改竄検知」「なりすまし検知」に焦点を当てて、それぞれどのような仕組みで実現されているのかを見ていきます。

## 盗聴防止

暗号化にも復号にも使える鍵の存在を前提にすれば、暗号化されたデータだけを通信経路に乗せればよいので盗聴されずにすみます。これを **共通鍵暗号方式（対称鍵暗号方式）** と呼びます。

![symmetric_key.png](https://qiita-image-store.s3.amazonaws.com/0/288168/ee15cead-9738-8ffb-0080-c4d7af9494b7.png)

共通鍵暗号方式で「 Alice と Bob は共通鍵をどのように共有すればよいか？」という問題が生じます。この問題を克服したのが **公開鍵暗号方式（非対称暗号方式）** です。

公開鍵暗号方式では暗号化と復号に別の鍵を使います。 **暗号化に使う鍵を公開鍵として** 配布する一方、 **復号に使う鍵を秘密鍵として** オフラインに保管しておけば、共通鍵暗号方式の鍵配送に伴う問題をクリアできます。

なお公開鍵暗号方式において、公開鍵と秘密鍵のペアは一意で、 **片方の鍵で暗号化されたメッセージは、対になる鍵でしか復号できません** 。

![asymmetric_key.png](https://qiita-image-store.s3.amazonaws.com/0/288168/d2a8679e-bd83-a74c-fe82-6ca1485bdfc3.png)

公開鍵暗号方式は共通鍵暗号方式に比べて高い処理負荷が要求されます。そこで、 **「公開鍵暗号方式で共通鍵を交換し、その後の通信は共通鍵暗号方式で暗号化する」** という方法により、鍵配送問題の解決と低い処理負荷を両立することが可能になります。これは **ハイブリッド暗号方式** と呼ばれています。

![hybrid.png](https://qiita-image-store.s3.amazonaws.com/0/288168/c3ba7ed6-21ce-655e-31ec-810ce7c1d2ef.png)

## 改竄検知

次に改竄検知についてです。以下の仕組みで、通信内容が改竄されてもそれに気付くことができます。

1. 事前に Alice と Bob との間で秘密の共通鍵を交換する。
1. Alice は、ハッシュ関数に **メッセージと共通鍵を入力して** ハッシュ値（ **ハッシュ値①** ）を計算する。
1. Alice はメッセージと **ハッシュ値①** を Bob に送信する。
1. Bob は、ハッシュ関数に **受信したメッセージと共通鍵を入力して** ハッシュ値（ **ハッシュ値②** ）を計算する。
1. Bob は、 **ハッシュ値①** と **ハッシュ値②** との値を比較する。2つのハッシュ値が等しければメッセージは改竄されていないと判断する。

![mac.png](https://qiita-image-store.s3.amazonaws.com/0/288168/7be46c3a-30ac-d546-af8a-f64dc5902219.png)


この仕組みの妥当性は、ハッシュ関数が持つ以下の特徴に依存しています。

- ハッシュ値からハッシュ関数の入力を探すことが事実上不可能
- ハッシュ値が等しくなるような、異なる入力の組を見つけ出すことが事実上不可能

ハッシュ関数の入力として、 **メッセージに加えて秘密の共有鍵を与える** ことにより、ハッシュ値の比較による改竄検知はより強固なものになります。このハッシュ値のことを **メッセージ認証符号 (Message Authentication Code, MAC)** といい、 MAC を導出するハッシュ関数のことを MAC 関数と呼びます。

秘密の共通鍵が Mallory に知られた場合、改竄検知は機能しなくなります。Alice だけでなく Mallory も、 Bob が行う MAC の比較をクリアすることができるようになるからです。つまり鍵配送問題が生じるわけですが、これは先述の公開鍵暗号方式で解決することができます。

## なりすまし検知

### 認証局

盗聴防止と改竄検知の仕組みを見てきましたが、 **「そもそも通信相手が意図した相手でないかもしれない」** という、なりすましの脅威が残っています。

通信相手から配布された公開鍵を使ってデータを暗号化したとしても、この **公開鍵が悪意ある第三者から配布されたものである場合、データは悪意ある第三者の秘密鍵で復号されてしまいます** 。通信相手が意図した相手であること、つまり、配布された **公開鍵が信頼できるものであること** が担保されてはじめて、盗聴防止や改竄検知が意味をなします。

では「公開鍵の信頼性は誰によって担保されるのか？」という問題に直面するわけですが、これは **認証局 (Certicfication Authority, CA)** という **無条件に信頼される機関** によって担保されます（実際に個々の認証局が絶対的に信頼できるかどうかは置いておいて、 PKI には無条件に信頼できる第三者機関が必要です）。

### 証明書とデジタル署名

SSL/TLS に対応した web サーバを公開するケースを例に挙げて、公開鍵の信頼性が認証局によって担保される流れを追っていきましょう。

![certificate.png](https://qiita-image-store.s3.amazonaws.com/0/288168/a034bb58-a5b9-3201-6ae3-49efb7660411.png)

#### 1. 証明書をリクエスト

サーバ管理者は認証局に対して、 **公開鍵の信頼性を保証する証明書** の発行を要求します。この要求を **Certificate Signing Request, CSR** といい、公開鍵および被証明者の情報を含んでいます。

#### 2. CA が署名して証明書を発行

CSR を受け付けた認証局は、サーバ管理者が信頼できるかどうかを審査します。審査の厳しさには段階があり、厳格であればあるほど、審査に通った暁にはそれだけ高い信頼性を担保してくれます。

審査に通った場合、認証局お墨付きの証明書が発行されます。このお墨付きのことを **デジタル署名** というのですが、その仕組みは公開鍵暗号方式そのものです。

盗聴防止の仕組みは「公開鍵で暗号化して秘密鍵で復号する」というものでしたが、デジタル署名では **「秘密鍵で暗号化して公開鍵で復号する」** という形で公開鍵暗号方式を利用します。 Alice と Bob の通信を例にとってこの仕組みを見ていきましょう。

1. Alice が秘密鍵と公開鍵のペアを生成する。
1. Alice が秘密鍵でメッセージを暗号化して、公開鍵とともに Bob に送信する。
1. Bob はこの公開鍵で暗号化されたメッセージの復号を試みる。
1. 復号できた場合、このメッセージの送信者が間違いなく Alice であることがわかる。

![digital_signature.png](https://qiita-image-store.s3.amazonaws.com/0/288168/b6413ace-c8b7-a869-fde3-ed0ca6dad31b.png)


ここで話を戻すと、証明書に付与されるデジタル署名とは **CSR 情報を認証局の秘密鍵で暗号化したもの** です。 **デジタル署名が認証局の公開鍵で復号できる** ということは、 **その署名が認証局によってなされたもの** であり、つまり **署名された（秘密鍵で暗号化された）内容は認証局によって認められたもの** であるということになります。

なお、デジタル署名として暗号化されたメッセージは実際には CSR 情報そのものではなく、 CSR 情報のハッシュ値です。こうすることで改竄検知も可能になります。

#### 3. 証明書をサーバに配置 

サーバ管理者は、認証局によって発行された証明書を自身の web サーバに配置します。

#### 4. ブラウザに証明書を送付

接続してきたブラウザに対して、サーバは自身の証明書を送信します。先述の通り証明書は **サーバ管理者の公開鍵** と **認証局による署名** を含みます。そのため証明書を送信することは、クライアントに対して **暗号化に使う公開鍵** と **その公開鍵の信頼性** を示すことに相当します。

#### 5. 証明書を発行した CA の公開鍵を取得

ブラウザは署名の正しさを検証するため、証明書を発行した **認証局の公開鍵** を取得します。

#### 6. 署名の検証を行い、証明証の正当性を確認

ブラウザは認証局の公開鍵でデジタル署名の復号を試みます（ **署名の検証** ）。復号に成功した場合、署名は正しく、したがってサーバの公開鍵は信頼できるものと判断することができます。

これでなりすましの脅威は排除され、安全な通信を行うための要素が全て出揃いました。

### 証明書チェーン

上の例では、無条件に信頼される認証局から直接証明書が発行されていました。このように **ブラウザから無条件に信頼される認証局** のことを **ルート認証局 (Root Certificate Authentication, Root CA)** といいます。

実際には認証局は階層構造になっています。この頂点に存在するのがルート認証局であり、 **ルート認証局を除く全ての認証局は、上位の認証局からその正当性が担保されなければなりません** 。そしてふつう、 **サーバの証明書はルート認証局よりも下位の認証局から発行** されます。この下位の認証局のことを中間認証局と呼ぶことにします。

サーバ証明書が中間認証局によって発行されたものである場合、クライアントは認証の階層構造を下位からたどりながら、ひとつひとつ署名の検証を実施していきます。以下の例を考えてみます。

- 登場人物は以下の通り。
   - Example Inc.
   - Intermediate Inc. （中間認証局）
   - Root Inc. （ルート認証局）
- Example Inc. の証明書（サーバ証明書）は Intermediate Inc. によって発行され、 Intermediate Inc. の証明書（中間証明書）は Root Inc. によって発行される。

このとき Example Inc. が提供する web サービスにアクセスしたブラウザは、以下の流れで Example Inc. のサーバ証明書の正当性を確認します。

1. Example Inc. の証明書（サーバ証明書）に記載された発行者情報を確認して、発行者である Intermediate Inc. の証明書（中間証明書）を取得する。
1. 中間証明書に格納された公開鍵を使って、 サーバ証明書に付与された署名を検証する。
【 *Example Inc. の正当性が Intermediate Inc. によって担保されていることがわかった。では Intermediate Inc. の正当性は？* 】
1. 中間証明書に記載された発行者情報を確認して、発行者である Root Inc. の証明書（ルート証明書）を取得する。
1. ルート証明書に格納された公開鍵を使って、 中間証明書に付与された署名を検証する。
【 *Intermediate Inc. の正当性が Root Inc. によって担保されていることがわかった* 】

Root Inc. はルート認証局であり常に正当性が認められているため、 **ルート証明書の署名検証にたどり着いた時点で全ての証明書の正当性が担保された** ことになります 。このような認証の階層構造を **証明書チェーン** といいます。

![certificate_chain.png](https://qiita-image-store.s3.amazonaws.com/0/288168/cd722e81-c539-190b-4676-5d73164ebb46.png)

なお、今回の例のようにサーバ証明書が中間認証局から発行されたものである場合、 web サーバには自身のサーバ証明書だけでなく中間証明書も配置する必要があります。ブラウザは **サーバから送信されたサーバ証明書と中間証明書、そしてブラウザ自身にあらかじめインストールされたルート証明書を全て手元に揃えることで証明書チェーンを完成させます**。

## さいごに 

ご指摘コメントお待ちしております。