Webセキュリティ覚書 : "HTTPS" 編 [ 初学者向け ]


# 通信中のセキュリティ
前回、[Webセキュリティ覚書 : "攻撃" 編 [ 初学者向け ]](https://qiita.com/Tsutou/items/4fd498f8ab2638bd5650)　にて、攻撃について書きました。
今回は続きとして**HTTPS通信**について、基礎の基礎、最低限の知識を共有できたらと思います。

最初、いくつ鍵あるんだ..とわけがわからなかったのを覚えています。(まだわかっていない)

# そもそも**HTTP**って？

今の時代、Webアプリケーションを作るときには、フレームワークを通して作ります。フレームワークを使うと、初学者でもある程度堅牢で、シッカリしたものを作れてしまうので、通信方法などは意識することは少ないと思います。

変化の激しい世界ですが、だからこそ職種を問わず、こういった長きに渡って不変の知識は勉強しておいて損はないかと思います。

**HTTP(Hyper Text Transfer Protocol)**は通信プロトコルです。


エンジニアとして転職するときに、この**HTTPプロトコル**に関する質問は面接でもよく聞かれ、凄く理解を求められていたような気がします。


インターネット(World Wide Web)の世界では、情報(HTML)をやり取りするための方法として、Webブラウザと、Webサーバー間で情報の伝達や意味づけが行われます。

ウィキペディア
>Hypertext Transfer Protocol（ハイパーテキスト・トランスファー・プロトコル、略称 HTTP）とは、HTMLなどのコンテンツの送受信に用いられる通信プロトコルである。 主としてWorld Wide Webにおいて、WebブラウザとWebサーバとの間での転送に用いられる。

HTTPは、シンプルでデータを要求する**HTTPリクエスト**とそれに応答して、要求されたデータを送り返す**HTTPレスポンス**の2つのやりとりを繰り返してWebページを表示してくれます。

HTTPはもっともっと奥が深いのですが、今回はHTTPSについての記事なので割愛します。
気になる方は以下の参考リンクや参考書籍がとてもわかりやすく書かれています。

記事
[超入門HTTPプロトコル： 第1回 HTTPプロトコルとは](http://www.atmarkit.co.jp/ait/articles/1703/29/news045.html)

書籍
[「プロになるためのWeb技術入門」](https://www.amazon.co.jp/%E3%80%8C%E3%83%97%E3%83%AD%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AEWeb%E6%8A%80%E8%A1%93%E5%85%A5%E9%96%80%E3%80%8D-%E2%80%95%E2%80%95%E3%81%AA%E3%81%9C%E3%80%81%E3%81%82%E3%81%AA%E3%81%9F%E3%81%AFWeb%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%92%E9%96%8B%E7%99%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B-%E5%B0%8F%E6%A3%AE-%E8%A3%95%E4%BB%8B/dp/4774142352)


# HTTPS

HTTPの通信というのは暗号化されていない平文の状態で行われます。（暗号化なしのテキストそのままの状態）盗聴されれば、そのまま入力した電話番号やカード情報が盗まれてしまいます。

またHTTPは[ステートレス(状態を保てない)](https://www.websec-room.com/2013/02/23/178)なプロトコルのため、サーバーやクライアントを認証する手段がありません。(セッション管理の不備をついた[セッションハイジャック](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%8F%E3%82%A4%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF)など、なりすましの危険性)

そこで、[HTTPS](https://ja.wikipedia.org/wiki/HTTPS)を使うことが推奨されます。


HTTPSは「HTTP over SSL/TLS」の略で、[SSL(SecureSockets Layer)/TLS(Transport Layer Security)](https://www.symantec.com/ja/jp/page.jsp?id=ssl-tls)プロトコルによって安全を保証した、より安全な接続でのHTTP通信のことを言います。

HTTPS通信を使うと、Webブラウザ上ではURLのプロトコル名が`https://`という表現となり、アドレスバーが緑色になります。

![スクリーンショット 2017-12-03 19.55.32.png](https://qiita-image-store.s3.amazonaws.com/0/187392/2d264062-117a-5672-0560-7b1912b1630c.png)


ソケットはプログラム(アプリケーション)の世界と[TCP/IP(インターネット・プロトコル・スイート)](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88%E3%83%BB%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB%E3%83%BB%E3%82%B9%E3%82%A4%E3%83%BC%E3%83%88)の世界を結ぶ特別な出入り口です。

[httpとhttps（SSL）の違いは、直球と魔球くらい違う](https://www.bloom-promotion.jp/journal/web-knowledge/http-https-ssl-difference.html)

# SSL証明書
**SSL証明書**は後ほど説明する、**認証局**がサーバー運営者の身元を保証することを示したデータになります。

HTTPS通信では、**`共通鍵認証方式`**、サーバー認証の際に**`公開鍵暗号方式`**を使っています。
つまり、**`共通鍵暗号化方式`**と**`公開鍵暗号化方式`**を組み合わせた**ハイブリット方式**が採用されます。

流れは以下になります。

1.<font color=red>クライアント</font>(ユーザーや管理者)が<font color=blue>Webサーバー</font>に接続要求します。
 

2.<font color=blue>Webサーバ側</font>から`公開鍵`付きのSSLサーバ証明書が送付され、<font color=red>クライアント側</font>のブラウザに搭載されるルート証明書にて署名を確認して、SSLサーバ証明書を検証します。そして、<font color=red>クライアント側</font>で`共通鍵`が生成されます。
 
3.<font color=red>クライアント側</font>で生成された暗号用の`共通鍵`を、<font color=blue>Webサーバ側</font>から送られてきた`公開鍵`を用いて暗号化し、サーバ側へ送信。

4.個人情報などの機密性の高いデータを、<font color=red>クライアント側</font>で保持している`共通鍵`で暗号化しサーバ側へ送信。<font color=blue>Webサーバ側</font>は、受け取った暗号データを<font color=blue>Webサーバ側</font>で保持している`共通鍵`で復号してデータを取得する


はい。**わけがわかりません。**
 

整理すると、こんな感じでしょうか..

# 流れ

![https.png](https://qiita-image-store.s3.amazonaws.com/0/187392/56382dbd-30e3-e66e-1953-62759e68a20b.png)

お互いが**公開鍵**、**秘密鍵**によって生成された**共通鍵**を保持したら、暗号化通信が始まる感じですね。


# 認証局( CA => Certificate Authority )
上記の**公開鍵**が本物であるかどうか、それを判断し証明するために**認証局**は存在します。
つまり、クライアントとサーバーが双方信頼する**第三者機関**がその立場に立ってくれます。

[認証局とは？](https://jp.globalsign.com/knowledge/ca.html)

以下、有名な認証局です。

- [Symantec](https://www.symantec.com/ja/jp/tls-ssl-certificates/)
- [ AWS Certificate Manager ](https://aws.amazon.com/jp/certificate-manager/)
- [GlobalSign](https://jp.globalsign.com/)
- [GeoTrust](https://www.geotrust.co.jp/)
- [Rapid SSL](https://ssl.sakura.ad.jp/rapidssl/rapidssl.html)
- [SecureCore](https://www.securecore.co.jp/)
- [cybertrust](https://www.cybertrust.ne.jp/sureserver/)
- [セコムパスポート](https://www.secomtrust.net/service/pfw/)
- [Let’s Encrypt](https://letsencrypt.org/)

まず、Webサーバーの運営者が認証局に**公開鍵**を提出します。認証局は**公開鍵**に対して、[デジタル署名](http://itpro.nikkeibp.co.jp/article/COLUMN/20060704/242422/)を施します。

これが**サーバー証明書**として発行され、サーバーはクライアントに、先ほどの流れで送付し、暗号化通信を行います。

クライアントは、**認証局の公開鍵**を証明書と共にうけとっているので、サーバーの公開鍵を認証したのが、上記を筆頭とした本物の認証局であることと、それが信頼に足る公開鍵だということを知ることができます。

SSL証明書には、上記のサーバー証明書以外にも、[クライアント証明書](https://jp.globalsign.com/knowledge/clientcert.html)と[コードサイニング証明書](https://jp.globalsign.com/service/codesign/knowledge/)があり、それぞれクライアント認証、プログラムの電子署名に使用されます。

また、Chromeデベロッパーツールのセキュリティタブより、認証局が確認できます。
QiitaはAmazonが認証しています。[ AWS Certificate Manager ](https://aws.amazon.com/jp/certificate-manager/)による発行となるのでしょうか。

![スクリーンショット 2017-12-04 22.26.52.png](https://qiita-image-store.s3.amazonaws.com/0/187392/d66e6aba-dfc8-8cf9-e298-1763b69a77d5.png)



また、サーバー証明書は、**攻撃者**であろうが誰でも発行できます。
ですので、信頼性のない独自認証局で発行したサーバー証明書は使用しないようにしましょう。

# **SSL**(Secure Socket Layer) / **TLS**(Transport Layer Security)



現在、HTTPSで使える規格は
**``SSL2.0/SSL3.0/TLS1.0/TLS1.1/TLS1.2``**となります。
**[TLS(Transport Layer Security)](https://ja.wikipedia.org/wiki/Transport_Layer_Security)**は**SSL(Secure Socket Layer)**がアップデートを繰り返した進化系です。基本的には、大枠は同じものです。
SSLと呼ばれていた期間が長かったので、現在は**TLS**を使うのが一般的なのですが、**SSL/TLS**や**SSL通信**と呼ばれるそうです。

これらの中で、**SSL2.0**はすでにブラウザでも初期設定で使用できなくなっているそうです。
また、**SSL3.0**にも脆弱性が発見され、原則としては使用禁止となっています。

つまり、HTTPS通信を使用する場合、TLS規格を使用しましょうということです。

[Template:ウェブブラウザにおけるTLS/SSLの対応状況の変化](https://ja.wikipedia.org/wiki/Template:%E3%82%A6%E3%82%A7%E3%83%96%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BTLS/SSL%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81%E3%81%AE%E5%A4%89%E5%8C%96)
[SSLとTLSの違いと脆弱性](https://www.symantec.com/ja/jp/page.jsp?id=ssl-tls)

# まとめ
HTTPSなんて言葉も知らないときに、自分でアプリケーションを作ったときWebRTC(ビデオ通話のAPI)を使ってみたのですが..。
カメラとマイクが起動しなくて苦労しました。
ですが、原因を探るとそもそも、SSL通信でないHTTP通信のアプリケーションに対してChromeはすでにその機能(マイクやカメラの使用)を**制限**しているので、SSL化しなければ不可能というオチでした。

それほどまでに、Webアプリケーションにおいて個人情報を扱う際、SSL/TLS通信を扱うことは今の時代、最低要件のように感じます。

人様の情報を預かるときには、必ずHTTPS通信を使いましょう。

最低限のことしか書けていませんが、よくわからんっていう人の導入になれば幸いです。
もっと勉強したい方は、上述した、各認証局のページがとても親切に書かれていて、参考になります。

足りない部分、間違っているところありましたらガンガン指摘していただきたいです。
長文お読みいただき、ありがとうございました。