Webの世界-HTTPS編-

# Webの世界-HTTPS編-
## 概要
この記事は[Webの世界-HTTP基礎編-](https://qiita.com/haseesah/items/6d9cb952bef8551d5eb9)の続きになります。  

上記記事でも少し触れたように、HTTPによる通信は全て平文で行われている。当然HTTPによる通信を行うにあたり、クライアントとサーバの間にはルータやプロキシサーバなどが介在しているため、そのどこかで通信を盗み見られたり、改ざんされたりする可能性が発生する。  
代表的な攻撃としては中間者攻撃(MITM攻撃)[^1]が知られるが、そのほかにもなりすましや盗聴、検閲などが容易に行われてしまう。  
そこで、HTTPによる通信をよりセキュアに行うためにSSL/TLSプロトコルを用いてHTTP通信を行うのがHTTPS通信である。  
現在、[w3techs](https://w3techs.com/technologies/details/ce-httpsdefault/all/all)によるとWeb上の通信は約55%がHTTPS通信であるとされる。  
現在メインストリームとなりつつあるHTTP/2.0が事実上HTTPSが前提のプロトコルであることを考えると、今後Web上の通信はほぼHTTPSが占めると思われる。  

本記事ではそのHTTPSの解説を行う。  

## HTTPSの仕組み
HTTPSは大きく以下のような仕組みで通信を行う。  

1. クライアントがサーバにHTTPSによる通信を要求する
2. サーバはサーバ証明書をクライアントに返却する(使用するプロトコルも伝える)
3. クライアントはサーバ証明書の正当性を検証する
4. サーバ証明書に付属するサーバの公開鍵で暗号通信用の共通鍵を交換する
5. 共通鍵を使用して暗号通信を開始する
   

![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292905/360266df-fba3-1c32-7055-767e2ad35e31.png)
![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292905/1a4cc572-8e83-82fc-2b9c-a577df0d1761.png)
![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292905/ce6def62-d06c-946b-45a3-ee3dff9b6924.png)


なお、使用するアルゴリズムによって若干違いがでる。  
以下で各ステップの解説を行う。  

### HTTPS通信を要求する(Client Hello)
クライアント、サーバ間でコネクションが確立された後、クライアントはサーバ側にサーバ証明書を要求する。(Client Hello)  
この時、クライアント側は対応可能な認証/暗号アルゴリズムをリストで提示し、選択をサーバに委ねる。  

なお、今回説明する方式ではクライアント側がHTTPSでの接続を要求するしかないが、サーバ側からHTTPSでの接続を要求することが可能で、それを**HSTS**(HTTP Strict Transport Security)という。  
詳細は割愛するが、これはHTTP通信を要求してきたクライアントに対し、サーバが```Strict-Transport-Security```ヘッダーを送り返すことでHTTPSによる接続を要求するようになる。

### サーバ証明書を返却する(Server Hello)
Client Helloの通信を受けたサーバは、以下の情報をクライアント側に返却する。(Server Hello)

+ サーバ証明書
+ 使用する暗号アルゴリズムの方式

使用する暗号アルゴリズムは、Client Helloで提示されたリストからサーバが対応可能なものを選択して返却される。

#### サーバ証明書
サーバ証明書はSSL/TLS、HTTPS通信において重要な位置を占めるものである。  
サーバ証明書は[ITU-T](https://www.itu.int/en/ITU-T/Pages/default.aspx)が制定した[X.509](https://www.ipa.go.jp/security/rfc/RFC2459JA.html)で規定されており、以下の要素で構成される。  

+ サイトの主体者(名前とドメイン名)
+ サーバの公開鍵
+ 証明書発行局名
+ 証明書発行局の電子署名
+ 有効期間
+ 証明書の基本情報
  + 証明書のバージョン
  + 電子署名に使われている暗号化方式
  + 通し番号 

なお、サーバ証明書は一つだけでなく、サーバ証明書を発行した認証局の証明書が連なりチェーンのようになっており、このチェーンを後述の正当性検証によって証明していく。  

サーバ証明書はオレオレ証明書をのぞき、基本的にはCA:Certification Authority(認証局)と呼ばれる第三者が発行/管理を行っている。  
後述する認証レベルによって確認する事項は違うが、証明書の発行時に申請元が正当であることを確認し、失効した証明書や危たい化した可能性のある証明書を失効させたりして管理を行っている。  
また、サーバ証明書は認証レベルによって以下の3つの種類が存在する。 

|名称|証明内容|信頼性|
|---|---|---|
|DV(Domain Validation) : ドメイン認証|ドメインの使用権|低|
|OV(Organization Validation) : 企業認証|ウェブサイト運営団体の実在性|中|
|EV(Extend Validation)|ウェブサイト運営団体の実在性|高|

DVに関しては、個人でも取得が可能ではあるが、OV以上は企業の実在性などを登記簿を利用して確認などをするため、ある程度の安全性が担保される。

### サーバ証明書の検証
Server Helloで取得したサーバ証明書は、そのままでは正当性が全く担保されていないため、クライアント側で検証する必要がある。  
正当性の証明に関しては、前述した証明書のチェーンを次々確認していく方式が取られる。  
概略図を下記に示す。  

![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292905/7bc1ecfc-65fa-d02b-b5ef-cab6c3d06f7c.png)

図で示すように、サーバ証明書チェーンは、起点となるサーバ証明書から、その証明書の認証局の証明書、さらに認証局の証明書を発行した認証局の証明書と数珠つなぎになっている。  
各証明書には発行した認証局のデジタル署名が付与されているため、その親の証明書に付属している認証局の公開鍵を用いてデジタル署名の正当性を検証する。  
チェーンを順に辿っていくと、最終的に発行者と主体者の名義が同一の**ルート証明書**と呼ばれる証明書が出てくる。  
このルート証明書を認証する認証局は存在しないが、各ブラウザやOSはあらかじめ信頼できる認証局の証明書がインストールされているため、それと比較することで正当性を検証する。  
なおルート証明書を発行する認証局をルート認証局と呼称し、日本では[グローバルサイン](https://jp.globalsign.com/) などが発行している。
### 鍵交換
上記の手順でHTTPS通信を行うサーバの正当性とサーバの公開鍵を手に入れることができたが、このままサーバの公開鍵を用いた通信の暗号化を行うのは現実的ではない。  
一般的に公開鍵と秘密鍵を用いたRSA暗号方式による通信方式は、計算に非常に時間がかかり、コストが高い。  
単発の通信ならともかく、HTTPSによる通信は頻繁の行われるため、処理速度のボトルネックになってしまう。  
そこで、HTTPSによる通信はRSAによる暗号化ではなく、AESを用いた暗号化で行い、AESで用いる公開鍵の交換をRSAで行う。  

AESで用いる公開鍵の生成方法は大きく二つの方式がある。

+ クライアント側で乱数を発生させてそれを用いる
+ クライアントとサーバでそれぞれ鍵の元を生成、交換して二つを合わせて生成する

どちらの方法で行うかはClient Hello、Server Helloのネゴシエーションで決定される。  
前述の通り、鍵の交換はサーバの公開鍵を用いて行う。

### HTTPS通信の開始
これでHTTPS通信を行う準備が完了したため、通信内容を共通鍵を用いて暗号化する。

### 問題点
HTTPSには構造上免れない問題点がいくつか存在するため、簡単に説明する。

#### 通信時間
今までの手順からわかるように、HTTPS通信を行うにあたりクライアントとサーバ間で何回か通信を行う必要がある。  
今回の例でいえば、Client Hello,ServerHello,鍵交換で最低1.5往復の通信が必要になり、そこがボトルネックになり得る可能性がある。  
これを解消するため、TLSのバージョンによってはセッションIDや事前共有鍵を用いたり、Client Helloから鍵交換を行って通信の往復頻度を下げることができる。  

#### 通信の安全性
HTTPSは非常に安全性が高いように思われるが、当然完ぺきではない。  
まず、HTTPSは通信の安全を担保するだけで、HTTPSの範囲外での安全性は担保できない。  
当然通信を行った相手がそもそも信頼できない可能性が存在する。  
前述のようにサーバ証明書は担保する内容に差異があり、個人で取得可能なものも存在し、フリーで証明書を取得できる[Let's Ecrypt](https://letsencrypt.org/ja/) というサービスも存在する。  

また、カザフスタンではルート証明書に政府が認証したものを強制し、HTTPS通信の傍受が可能になるのではないかと批判が起こっている。[^2]

## まとめ
普段何気なく利用しているHTTPS通信の中身を追ってみた。  
実際にはSSL/TLSレイヤの話はあまりしていないので、その辺に突っ込んだ内容も調べてみたい。

[^1]: ルータが中間者攻撃の起点となった例(https://www.theregister.co.uk/2003/11/07/help_my_belkin_router/)

[^2]: https://ascii.jp/elem/000/001/902/1902340/