HTTPS通信ってどうやってるんだろ？を改めて調べる

# はじめに
Let's Encryptサービスを使うとタダでSSL設定ができるねってことはわかったけど。
ふと「HTTPSってなんで安全っていえるんだろ？」ってのが改めて不思議だったのでしらべることにした。

# HTTPSってどうやって暗号化をしているのかを改めて。
これが一番わかりやすい。HTTPS通信は「公開鍵方式」と「共通鍵方式」を組み合わせていたんだってことがわかる

https://college.globalsign.com/ssl-pki-info/ssl-encryptions/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/6846e7a2-8b79-7a21-c1ba-434c0efe8e0e.png)

最初に、クライアントはWebサーバから"公開鍵"を証明書付きでもらってくる。
クライアントは証明書をチェックして公開鍵が適切なWebサーバから送られたことを確認する
クライアントは「共通鍵」を作成して、"公開鍵"で暗号化してWebサーバへおくる。
Webサーバは「共通鍵」を自前の"秘密鍵"で復号化。以後、クライアントとWebサーバは、「共通鍵」を使ってHTTPS通信を実現するってことか。
これなら安全な気がする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/4aa0d0f6-a994-d743-5d67-4007f83945a8.png)

# SSL証明書が正しいからって公開鍵が正しいってなんで言えるの？
素朴な疑問で、Webサーバから証明書付きで公開鍵が送られてきた、として
SSL証明書を適当にWEBサーバから取得して、それで自前で公開鍵作ったらイケるんじゃないの？
っておもったので、証明書がいかほどすごいのかを追加で調べる

## 証明書ができるまで

https://dev.classmethod.jp/articles/ssl-certificate-system/

まず、証明書はオレオレ証明書ってのもあるけど、
基本的には「認証局」っていうちゃんとした機関に申請（このときのデータをCSRって呼んでる）して、OKだったら、「署名付き証明書」を発行してもらう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/ae16828f-3e00-b1d0-c308-31c89ad25925.png)

証明書の申請には、
* 会社の組織名
* 所在地
* ドメイン名
* 公開鍵
などの情報が必要。なので、この時点で公開鍵を「認証局」に渡すことになる。

### 署名済み証明書の作り方
認証局は単純に「OKOK」と返事をするだけでなく、ちゃんと「署名済み」証明書を作成して、それをサーバにお返ししている。

署名というのは具体的には、「認証局」が所有している"秘密鍵"で暗号化したCSRデータっていう理解でよいと思う。
なので、「署名済み証明書」は”CSR+署名データ”の状態を指す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/9cf43deb-b3d4-bb18-0cb1-b6776c91184b.png)

## 証明書の正しさを確認する方法（検証）
１．署名済み証明書を、CSRと署名データの２つに分ける
２．CSRをハッシュ関数にかけてハッシュ値を取得する
３．署名データを検証鍵を使って復号して、ハッシュ値を取得する
４．２．と３．を比較して一致したら成功！この署名は間違いなく認証局が発行したものだと確認できました。
ってことになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/75dfd1c5-769b-133a-58e5-a7f83d2076a6.png)

なお、ここでいうハッシュ関数ってのは、↓↓によると現在はSHA-2を指すようで、

https://tech-camp.in/note/technology/44817/#SSL

どんな関数使ってるの？ってのは証明書でいうところの「署名ハッシュアルゴリズム」で確認できる。
↓↓のケースだとsha256でハッシュ化しましたよってことになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d06c24b0-8af9-d28f-3b5d-453f8eb7e9f0.png)

## 検証鍵って何？
検証鍵ってのは「認証局」が署名作成時に使用した”秘密鍵”の対となる”公開鍵”のこと。
で、OS/ブラウザを作ってる各種ベンダー（MicrosoftとかAppleとか）は監査基準を満たした認証局のルート証明書を収集して
これを定期アップデートの形でルート証明書の検証鍵を更新し続けている。
なるほど、、、Windowsの認証局ストアにおいてある証明書ってのは「検証鍵」のことだったのか。
スケールが大きすぎて全然理解できなかった。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d2d79219-112f-5946-0353-141919e71ce8.png)

## で、話を戻して、署名が正しかったら、なぜ公開鍵も正しいと言えるのか？を振り返る
署名は、検証することで間違いないことはわかりましたよ、と。
じゃあ、例えばwww.google.comの公開鍵と署名付き証明書を勝手に盗用して自分のサイト（watyanabe.com)のHTTPS通信利用に使えないかな？ってちょっと考えた。

…落ち着いて考えたら、そもそものところで公開鍵を持っててもそれに合う秘密鍵がないからHTTPS通信成立しないな。

じゃあ、公開鍵はこちらで用意して、署名付き証明書をwww.google.comのものを盗用したらどうだろうか？
…冷静に考えたら、ブラウザの処理で取得した証明書に記載されているドメイン名とアクセス先のドメイン名が一致するかどうか位普通にチェックするよな。。。

じゃあ、公開鍵もこちらで用意して、署名付き証明書も自分で用意するしかないのか。よその人のドメイン証明書の盗用は難しそうだ。

署名は公開鍵情報＋ドメイン名の情報を使って作るから、証明書は各ドメインに対してひとつ、しかできないってことも分かってきた。
まぁ検証もするから正しいっていうのはよくわかった。

# 中間認証局ってなんであるの？
セキュリティ向上のため。だそうです。
ルート認証局がやられちゃって「証明書失効リスト(CRL)」入りした場合、その認証局から発行された証明書は
HTTPS通信できない。でも、間に中間認証局を経由しておけば、クライアントはルート認証局が証明書を再発行する間も
中間認証局の証明書を使って証明できるってわけ。

あと、中間認証局に対して証明書を申請すると、「SSL証明書」に加えて「中間証明書」も発行される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/f7606374-78d1-4988-2e19-7e848c249096.png)

# 中間認証局の検証はどうやるの？
中間証明書は、PCにプリインストールされている検証鍵（ルート証明書）を使う。
中間認証局が発行したSSL証明書は、中間証明書から取得できるのでこれを使う。
Webサーバへの公開鍵はSSL証明書から取得できるのでこれを使う。
といった具合で、公開鍵を拾っていくスタイルになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/5ffe24e3-bd89-e42e-055e-d2dcf52288c4.png)

# 最後に実際の証明書を見てみよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8c7e36bb-d175-cdd3-7210-eb7752599c72.png)

qiita.comはamazonが証明書を発行しているようだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/48e0a4ba-5d58-6325-e3e7-701e2431f862.png)

思った以上に中間認証局がいて焦る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/532277fc-473c-1638-bffd-3d4295227da7.png)

ちなみに、SSL証明書の公開キーはコチラ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/3e243831-b9cc-4f7c-e22c-cecd51dcb60d.png)

署名データは…見当たらなかったけど、そもそも、この証明書データが見えている時点で
署名データが検証鍵で復元された結果なんではなかろうかと思うと、
この証明書データそのものが署名データだったもの、ということなのかもしれない。

# オマケ：opensslでの検証のやり方
あとでゆっくり検証するけど、↓↓のサイトによると、opensslで署名作成した場合、検証するには
公開鍵データと署名データの２つで検証を行うようだ。やっぱり証明書は公開鍵とセットであることが必要ってことがこれでもわかる

https://memo.open-code.club/OpenSSL/%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB/%E9%9B%BB%E5%AD%90%E7%BD%B2%E5%90%8D%E3%81%A8%E6%A4%9C%E8%A8%BC.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/81f02730-db4f-fac0-da8d-97784f553c02.png)