SSL/TLSの基本

# まとめ
* SSL/TLSの機能ってなに?
  * 通信相手を識別し、なりすましを防ぐ **「認証」**  
    ※識別できても通信内容を差し替えられると意味がないので **「改ざん検知」** もある
  * 通信内容の漏洩を防ぐ **「暗号化」**
* SSL/TLSってどんな技術?
  * 鍵交換・認証・暗号化・メッセージ認証コードの**4要素のハイブリッド暗号**
  * 認証のために、**サーバ証明書** ( サーバ用の公開鍵証明書、SSL証明書とも ) を使用する
  * **サーバ証明書の信頼性を担保するPKI**の仕組みも考えると**全部で5要素**
  * 公開鍵暗号と共通鍵暗号のハイブリッド? **そう覚えている人は一旦忘れた方がいい**
* SSL/TLSで意識することってなに?
  * 大事なのは**ドメイン名**。なぜなら認証・PKIで **「通信相手がドメイン名通りのサイトであること」** を保証する技術だから
  * DVとかEVとか色々あるけど、**証明書の種類は正直割とどうでもいい**
  * サーバ証明書は「ドメイン名の示すサイトの本物のサーバ」であることを示す、**文字通り身分証明書のようなもの**であって、**サイト自体の信頼性とは関係ない**  
    ※証明書を発行する認証局は信用調査会社じゃない

# SSL/TLSってどんな技術?
## 導入
世間一般的には「公開鍵暗号と共通鍵暗号のハイブリッド」とよく言われます。
しかし、**そこから想像される仕組みは大体間違っています**( 或いは部分的なものでしかありません )。
そう覚えてる人は、**一回忘れましょう**。

代わりに分かり易い指標があります。
老舗の暗号ライブラリ・ツールであるOpenSSLでは、**SSL/TLSを4つの要素で整理**しています。

これは、Linux等で`openssl`コマンドの`ciphers`サブコマンドを実行することで見られます。

```shell-session:CentOS7(OpenSSL1.0.2k)でのciphers
$ openssl ciphers -v
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
…
DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
DHE-DSS-AES256-SHA256   TLSv1.2 Kx=DH       Au=DSS  Enc=AES(256)  Mac=SHA256
…
DH-DSS-AES256-GCM-SHA384 TLSv1.2 Kx=DH/DSS   Au=DH   Enc=AESGCM(256) Mac=AEAD
…
AES256-GCM-SHA384       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(256) Mac=AEAD
…
```

ciphersサブコマンドの出力は、Cipher Suite ( 暗号スイート ) という、SSL/TLSでの**暗号方式の組み合わせ**をリストアップしたものです。
この出力にあるように、OpenSSLでは**Kx, Au, Enc, Mac という4要素**として整理をしているのです。

## 4つ要素の詳細
では、このKx, Au, Enc, Macの4つの要素についてです。ちょっと順番を変えていきます。

* Enc ( **Enc**ryption: 暗号化 )
  * 文字通り、暗号化による**通信データの秘匿**を行う機能。
  * サーバ・クライアントでお互いに送信するデータを**暗号化**し、逆に受信側で**復号**を行う。
  * AES等の**共通鍵暗号**を用いる。
* Mac ( **M**essage **A**uthentication **C**ode: メッセージ認証コード )
  * 通信データの**改ざんがないかどうかを調べる**機能。
  * 確認用のデータである「メッセージ認証コード」を付与してデータを送信し、受信側で整合性を見る。
  * 以前は、データと共通鍵を混合してハッシュを計算する、**HMAC** ( Hash-based MAC ) が使われていた。
  * 近年は、Encの共通鍵暗号がMacの機能も兼ねる **AEAD** ( Authenticated Encryption with Associated Data: 認証付き暗号 ) として、AES-GCM等が使われる。
* Kx ( **K**ey e-**X**change: 鍵交換 )
  * Enc,Macに使用する**共通鍵の元になるデータを秘密裏に共有**する機能。
  * 主にECDH等の**鍵交換** ( 公開鍵暗号の1種 ) を用いる。
* Au ( **Au**thentication: 認証 )
  * **鍵交換とも連携し**、サーバ側が**なりすましでないことを確認**する機能。
  * ECDSAやRSA署名等の**電子署名** ( 公開鍵暗号の1種 ) を主に用いる。
  * **サーバ証明書の正当な所有者**であることを、証明書に含まれる公開鍵に対応する秘密鍵を使って証明する。
  * 電子署名の場合、署名を送ることで**秘密鍵自体を提示することなく**、秘密鍵の所有を証明する。  
    ※署名を作れるのは秘密鍵の所有者のみという理屈

この4要素の中で、Enc,Macは共通鍵を使った技術であり、Kx,Auは公開鍵暗号を利用するものです。
※公開鍵暗号については、記事「[2つの公開鍵暗号](/angel_p_57/items/897bf94160be8d637585)」で紹介しています。

なお、5つ目の要素であるPKIは、公開鍵暗号の1種である電子署名を利用して、サーバ証明書の保証を行うものです。その保証とは、SSL/TLSの場合は**サイト(ドメイン名)と公開鍵が確かに対応していること**についてです。
PKIそのものの詳細については、記事「2つの公開鍵暗号」の[PKI(公開鍵基盤)](/angel_p_57/items/897bf94160be8d637585#pki%E5%85%AC%E9%96%8B%E9%8D%B5%E5%9F%BA%E7%9B%A4)をご覧ください。
この**サーバ証明書に含まれる公開鍵はAu(認証)の手続きのために使用**します。

## 各要素の位置づけ
上で挙げた各要素の位置づけ・関連を図示すると次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/500c04f2-420e-b438-e7d0-dd2d93fc19b0.png)

近年のAEADを使う方式だと、以下のように、EncとMacがひとまとめになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/b9b89607-6996-84b9-dae8-7fe5b7639d62.png)


# 認証と証明書
## サーバ証明書の役割
上で説明した通り、サーバ証明書の役割は次の2つです。

* 認証の手続きで使用する公開鍵を提供すること
* その公開鍵とサイト(ドメイン名)の対応を保証すること

これはちょうど、身分証明 ( と、自動車の運転資格の証明 ) に使われる「運転免許証」に類似しています。
運転免許証が、ある人に対して、その人を見分けるための情報 ( 顔写真 ) を示すのに対し、サーバ証明書は、あるドメイン名に対して、認証に使う公開鍵を示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/46e6ff06-16af-1756-1e70-ac760c6d1ea4.png)
※画像はイメージです

もちろん運転免許証とサーバ証明書は別のものですので、以下の表のように色々違いがあります。

| 項目 | 運転免許証 | サーバ証明書 |
|:----|:--------|:--------|
|識別子|運転者の氏名|サイトのドメイン名<br>※複数あるいはパターン指定可能|
|本人確認用情報|顔写真|認証用の公開鍵|
|発行者|各地の公安委員会<br>※委員会印の印影付き|認証局という種類の組織<br>※認証局による電子署名付き|
|目的|運転できる自動車の種類を示す|公開鍵がサーバ認証用途であることを示す<br>※一般の公開鍵証明書には様々な用途がある|

なお、サイトの識別をドメイン名で行うようになっているのは**HTTPS(HTTP over SSL/TLS)がそのように要請しているから**であって、SSL/TLSそのもののきまりではありません。が、HTTPS以外であっても状況は似たようなものと考えられるため、一緒くたにして説明しています。
※細かいことを言うと、IPアドレスにより識別する方法もあります。

このドメイン名は、証明書の **SANs(Subject Alternative Names)** という項目で管理します。
この項目では、複数のドメイン名や、ワイルドカード ( アスタリスク ) によるドメイン名パターンを指定することができ、1つの証明書を複数のドメインで共有することができます。
もしSANsがない場合は、伝統的に CN(Common Name) の内容がドメイン名とみなされます。
例えばこの qiita.com の証明書の場合、Windowsの証明書ビューアで以下のように見えます。
※ブラウザでサイト閲覧する場合は、ブラウザがURLのドメイン名と突き合わせて自動的にチェックしますので、あえて手動で確認する必要はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/1b8999ef-6bd6-6ef7-987d-985736352614.png)

## 認証と鍵交換の連携
さて、Au(認証)では公開鍵暗号の1種である「電子署名」を使うのが基本です。
次のように、**正しい署名が作れるのは秘密鍵の持ち主だけ**ということを利用し、**秘密鍵そのものを提示することなく秘密鍵の所有を証明**します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/1ea1f7e8-c3b7-a472-0d70-24ff5b0469fb.png)

ただし、ここで問題となるのが、上の図中の「認証用データ」です。
サーバは通信のたびに「正しい」署名データを各所にばらまくことになるので、認証用データを都合よく決めることができてしまうと、**署名の流用でなりすましされるおそれ**があります。
これは**電子署名単独では解決できない問題**です。

一方で、Kx(鍵交換)に使う公開鍵暗号の[「鍵交換」](/angel_p_57/items/897bf94160be8d637585#鍵交換)も**単独では問題**があります。
それは、**鍵交換用のお互いの公開鍵が第三者にすり替えられると中間者攻撃(MITM)という介入を許す**という問題です。
※鍵交換用の公開鍵・秘密鍵は都度使い捨てにしますし、そもそもPKIの保証の範囲外にあります。

そこで、Au(認証)とKx(鍵交換)を連携させることで、これらの問題に対処しています。
それは、次の図のように**鍵交換用の公開鍵の一方から認証用データを作り**署名対象とすることです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/81b6715f-1b3e-f66c-f4be-5f243a1cc0ff.png)

このようにすることで、それぞれの問題への対処になっているのです。

* 署名の流用への対処  
  認証用データが鍵交換用の公開鍵に紐づいているので、署名を流用しようとしても鍵交換が成立しない。  
  ※鍵交換用の秘密鍵は表に出ないので、鍵交換用公開鍵・秘密鍵と署名の3点を揃えることはできない
* 鍵交換用公開鍵のすり替えへの対処  
  一方の公開鍵が署名によって保護される形になり、すり替えを検知することができる。  
  ※両方保護しなくても、一方のみで十分

なお、どちらの鍵交換用公開鍵を使うかは、SSL/TLSのバージョンによって異なります。
TLSv1.2まではサーバ側の公開鍵、TLSv1.3では両方の公開鍵を使います。
※当初、TLSv1.3ではクライアント側のみと誤解していましたが、記載を修正しました。

## サーバ証明書の種類
上で、サーバ証明書を運転免許証に喩えました。
ここで、運転免許証の発行を受ける際、**道交法の知識と運転技術に関する審査**がありますが、サーバ証明書にそういった資格審査があるわけではありません。
認証局が行うのは、あくまで**申告されたドメイン名のサイトの運営者かどうか**という身分確認に過ぎません。

ただ、その身分確認には3つの段階があり、それにより証明書にも、DV,OV,EV の3種類があります。

以下、その種類の話となりますが、先に注意事項として、**この種類の違いをユーザが気にする必要はほとんどありません**。
そのことは、ブラウザでの各証明書の扱いにも現れていて、パッと見ではほとんど違いがないのです。もちろん、わざわざ手動で詳細を確認する意味もありません。

では、それぞれの種類の概要です。

* DV ( Domain Validation )  
  認証局は、申請者が**申告されたドメイン名のサイトの運営者であること**のみ確認します。
* OV ( Organization Validation )  
  DVの確認に加え、認証局は、申請時に申告された通りの組織が運営者となっているか、**組織としての本人確認のようなもの**を行います。  
  **証明書に組織情報が記載**されます。
* EV ( Extended Validation )  
  OVと類似していますが、組織としての本人確認が更に厳しく行われます。  
  **ブラウザで組織情報が表示される**ようになります。

以下、実際のブラウザ ( Google Chrome ) での表示の違いです。
※証明書情報は、証明書表示ウインドウを別途出して確認しています。

なお、これは投稿時点(2020年1月)の表示例であり、それ以降細かな表示や、サイトで採用している証明書の種類が変わる可能性があることにご注意ください。
※例えば2022年4月時点で、各種ブラウザでのEVに対する組織名表示は大分目立たなくなりましたし、Googleの証明書はOVからDVに変わりました ( OVのサイトの事例を確認したければ、他にはマイクロソフト等があります )。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/e8ec9036-24bc-c5dc-b261-64b738c312f0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/fd025054-cf72-c026-14fa-b45d8071f93a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/8e14c545-525d-21a2-749f-609cb33e46d8.png)

## サーバ証明書の種類について補足
### 実在性の確認  
OV/EVでの「組織としての本人確認」のことは、よく「実在性の確認」と説明されます。
それは、「自称○○会」など**法的な地位がない組織だと本人確認のやりようがない**からであって、これは**前提条件の部分**を指している表現です。
「法的な地位」については認証局や、あるいは活動している地域(国)によって判断基準があるでしょうが、日本であれば概ね「**法人登録しているか**」で見ることができます。つまり、会社法人である一般の企業であれば規模を問わずクリアしている条件ですが、たとえ地元で存在が公的に認知されているとしても、法人登録をしていない多くの町内会等は対象にならないということになります。
また、あくまで「組織」であることが前提で、個人は対象とならないのが基本です。とは言え、[cybertrust社のように「個人事業主」も可としている認証局の例](https://www.cybertrust.co.jp/sureserver/apply/sole.html)もあり、「法的な地位」の詳細は認証局に確認した方が良いでしょう。

### 信頼性の違い
一般に、DV<OV<EV の順で信頼性が高まると言われます。
それは、証明書に組織情報が載る点や、OV,EVの方が発行料金が高い点から言われていることで、それ自体は誤りではないですが、**しかし「認証局が確認した内容としてユーザに見えるもの」という意味では過信できるほどの違いがあるとは見做せません**。そのため、前章では「種類の違いをユーザが気にする必要はほとんどありません」と説明しています。
※言葉の印象から、OVやEVの方が**なにか信用調査があって悪質な団体が排除されているのではないか**と勝手読みする人も後を絶たないのですが、そんなことも特にありません。

なぜ気にする必要がないかというと、**サイトを識別するのがドメイン名**であることから、**そのドメイン名のサイトの運営者かどうかが最重要ポイント**であって、組織情報はあくまで付加的なものでしかないからです。
実際、一番信頼性が高いとされるEVの場合、以前はブラウザ上で大々的に組織名が表示されましたが、**今ではほとんど目立たない表示に変更**されており、「サイトの運営者かどうか」「組織情報が何か」両者の重要性の比重を如実に表していると見做せます。
※どんなに手間をかけて組織の本人確認を行っているにしても、付加される組織情報が単に組織名・所在地に過ぎない点も大きいと言えます。**ユーザが知りたいのは「会社名が○○である」という情報ではなく、「自分が知っているあの会社と同じ組織か」であって**、似ているように見えて両者には大きな隔たりがあるからです。

ただ、**DVに関しては「運営者であることの確認」を行う上での技術基盤の観点から危うさがある**とも言えます。
近年、DV専門ながら無料での証明書発行を行う[Let’ｓ Encrypt](https://letsencrypt.org/ja/)という認証局が広く利用されるようになりました。このLet's Encryptや、他でもDVの証明書を発行する認証局は、**ドメインの運営者かどうか判断を自動化する技術**を導入しており、昔のメールベースでの確認が主体のDVとは一線を画します。
自動化を行うということは、**その基盤をDNSというシステムに大きく依存する**ことを意味します。しかし、あまり注目されないことですが、長年の運用実績があるにも関わらず**DNSは実装面でも運用面でもとても十分な信頼性があるとは言えません**。自動化によって、**DNSの弱点を突かれることがいつでもニセ証明書発行からサイト乗っ取りにつながる**というリスクを抱えている面もあり、今後どのように情勢が変化するか注意する必要があると言えます。
参考: [2019年のWIRED.jpの記事](https://wired.jp/2019/04/18/sea-turtle-dns-hijacking/) ( [英語版の元記事](https://www.wired.com/story/sea-turtle-dns-hijacking/) ) のように、実際にDNSハイジャックからニセ証明書を取得してのサイト乗っ取り(中間者攻撃)の報告事例もあります。

# 余談
## 電子署名以外の認証
上では、鍵交換→公開鍵暗号の「鍵交換」、認証→公開鍵暗号の「電子署名」が基本だと説明しましたが、TLSv1.2までは、両者を兼用する方式もありました。
丁度次の図のようなイメージになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74396/5e2e2f24-0aba-75f7-ebf8-094afd4f5dc7.png)

これは、公開鍵暗号の「暗号化 ( 狭義公開鍵暗号 )」あるいは「鍵交換」を、サーバ証明書にある公開鍵で行うことでKx(鍵交換)をまかない、Kx(鍵交換)が正しく成立したことをチェックしてAu(認証)とするものです。
※鍵交換+電子署名の場合、鍵交換用の公開鍵・秘密鍵は使い捨てであることに注意してください。

「暗号化」を使用する方式については、記事「2つの公開鍵暗号」の[狭義公開鍵暗号](/angel_p_57/items/897bf94160be8d637585#%E7%8B%AD%E7%BE%A9%E5%85%AC%E9%96%8B%E9%8D%B5%E6%9A%97%E5%8F%B7)にある「(狭義)公開鍵暗号に基づく鍵交換」をご覧ください。

この方式は長らく使われていたものの、もともと**証明書に対応する秘密鍵が漏洩すると過去の通信のKx(鍵交換)が解読され通信データの漏洩につながる**という問題があり、数年前から使われなくなりました。そしてTLSv1.3で廃止となっています。
※以前使われていたのは、この問題が現実的な脅威と見なされていなかったことや、処理性能上有利であったことが原因であると考えられます。

## よくある誤解
以下、SSL/TLSに関する説明でよくある誤解について紹介します。

* 証明書に含まれる公開鍵で共通鍵を暗号化する  
  これは、上の[電子署名以外の認証](#電子署名以外の認証)で紹介している方式の簡易版の説明と言えます。しかし、**鍵交換+電子署名という基本の方式を忘れている**上に、**今では廃止されている**ものです。  
  大昔のSSLv2の説明ならまだしも、いい加減ボツにすべきと言えるでしょう。
* SSLやサーバ証明書はサイトの信頼性を保証するもの  
  SSL/TLSは**接続先が意図したドメイン名のサイトかどうか**を保証するものであって、サイトの信頼性 ( 運営者の善性、フィッシングサイトでないこと、有害コンテンツがないこと ) の保証とは無関係です。  
  加えて、証明書を発行する認証局も、そのサイトや運営者の**信用調査を業とする組織ではありません**。  
  ※フィッシングサイト/マルウェアチェックを独自に行う認証局もありますが、ユーザがわざわざ手間をかけて、認証局と実施しているサービスを調べ、その信頼度を判断するのは無理があります。
* EVの証明書の方が(DV,OVに比べ)信頼性がある  
  **サイトの正当な運営者かどうか**という意味ではDV,OV,EVどれも変わりません。  
  もちろん、EVの方が証明書発行のコストは大きくなります。が、コストをかけているから信頼できると考えるのは短絡的だと言えます。  
  ※統計上は違いは出るかも知れませんが、「今アクセスしているサイトがどうか」の判断とは別物です

# 終わりに
記事「[2つの公開鍵暗号](/angel_p_57/items/897bf94160be8d637585)」で書ききれなかったハイブリッド暗号の事例として、SSL/TLSを取り上げました。
そろそろステレオタイプな伝言ゲームでなく、正しい理解に基づく情報が広まることを願ってやみません。