第5章 アプリケーション層|5-3|コース全体 19回中18本目
HTTPとHTTPS(TLS) ― 何が違うのか
HTTPは何をするプロトコルで、HTTPSはそれに何を足したものか。リクエストとレスポンスの形から、TLSハンドシェイクの要点、証明書とCAが保証することまでを解説します。
HTTPSは、HTTPに「暗号化」「改ざん検知」「相手の確認」を足したもの
HTTPは、Webブラウザとサーバーがデータをやり取りするための取り決め(プロトコル)です。 ただしHTTP自体には暗号化のしくみがなく、通信の中身はそのまま経路を流れます。HTTPSは、このHTTPをTLS(Transport Layer Security)という暗号化のしくみで包み、暗号化・改ざん検知・相手の確認の3つを足したものです。
HTTPは、1回のリクエストとレスポンスでできている
HTTP通信の基本は単純です。クライアント(ブラウザ)がリクエストを1回送り、 サーバーがレスポンスを1回返す。この1往復の繰り返しで、Webページは組み立てられています。 1つのページを表示するために、HTMLや画像・CSSの数だけこの往復が発生します。
GET /articles/http-https/ HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 # 1行目:メソッド(GET) パス(/articles/http-https/) バージョン # 2行目以降:ヘッダ(宛先ホスト名や使用ブラウザなどの付加情報)
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Content-Length: 5120 <html>...</html> # 1行目:バージョン ステータスコード(200) 理由句(OK) # 2行目以降:ヘッダ、空行を挟んで本文(実際に表示するHTML本体など)
リクエストの1行目にあるメソッドは「何をしたいか」を表します。主なものは次の4つです。
| メソッド | 意味 |
|---|---|
| GET | リソースを取得する(読み取り) |
| POST | 新しいデータを送って作成・処理させる(フォーム送信など) |
| PUT | リソース全体を置き換える |
| DELETE | リソースを削除する |
レスポンスの1行目にあるステータスコードは「結果がどうだったか」を3桁の数字で表します。 代表的なものは次の4つです。
| コード | 意味 |
|---|---|
| 200 OK | リクエストが成功した |
| 301 Moved Permanently | このURLは恒久的に別の場所へ移動した |
| 404 Not Found | 指定したリソースが見つからない |
| 500 Internal Server Error | サーバー側の処理でエラーが起きた |
URLの先頭が http:// の場合は80番ポート、https:// の場合は443番ポートに向けて、この往復が行われます。
HTTPの弱点:中身がそのまま流れる
HTTPのリクエストとレスポンスは、暗号化されずに、先ほどの例で見たような文字列のまま経路を流れます。 家庭内LANからインターネットに出るまでの間には、公衆Wi-Fiのアクセスポイントやプロバイダのルータなど、 いくつもの中継地点があります。そこに悪意のある第三者がいれば、通信の中身をそのまま読むことも、 途中で書き換えることもできてしまいます。
ログインフォームに入力したパスワードや、クレジットカード番号、Cookieに入った認証情報がHTTPのまま流れていれば、 それらはすべて経路上の第三者に読まれる可能性があります。書き換えの側も深刻で、 表示されるはずのないページに差し替えられたり、広告や不正なスクリプトを勝手に埋め込まれたりする被害が起こり得ます。
HTTPSは、HTTPをTLSで包んで3つを足したもの
TLSはHTTPの下に入って通信路を保護するしくみで、HTTPの中身自体を書き換えるものではありません。 HTTPSは「HTTP + TLS」という構成で、TLSが次の3つを足します。
- 1
暗号化
中身を読めない形に変換する。経路上の第三者が盗み見ても内容が分からない。
- 2
改ざん検知
途中で内容が書き換えられていないかを、受け取った側が確認できる。
- 3
相手の確認
証明書によって、通信相手が本当にそのドメインの持ち主かを確かめる。
HTTPは、クライアントとサーバーが平文のまま直接つながります。HTTPSはその間にTLSハンドシェイクという段階が入り、 証明書の確認と鍵の共有を済ませてから、暗号化した通信に切り替わります。 この段階がある分だけ、HTTPよりも1往復あたりの手間は増えますが、経路上の第三者から内容を守れます。
最近はHTTP/2やHTTP/3という新しいバージョンも使われていますが、 「リクエストを送り、レスポンスを受け取る」という基本のやり取りは変わりません。
TLSハンドシェイクの要点
TLSハンドシェイクは、TCPの3ウェイハンドシェイクでコネクションが確立した後、 実際のデータをやり取りする前に、クライアントとサーバーの間で行われる準備の手続きです。 目的は2つ、相手が本物かを確認することと、その後の暗号化に使う鍵を安全に共有することです。
サーバーはまず証明書をクライアントに送ります(①)。証明書には、サーバーの公開鍵と、 そのドメインの情報が入っています。クライアントは、その証明書が信頼できる認証局(CA)の署名を持っているかを確認します(②)。 確認が取れたら、クライアントはこれから使う共通鍵のもとになる情報を、証明書に入っていた公開鍵で暗号化してサーバーへ送ります(③)。 これで両者だけが共通鍵を知っている状態になり、以降のリクエストとレスポンスの本文は、その共通鍵で暗号化してやり取りされます(④)。
つまり、公開鍵暗号は①〜③の「相手の確認」と「鍵の受け渡し」だけに使われ、実際のページの内容そのものは共通鍵暗号でやり取りされます。
なぜ公開鍵暗号と共通鍵暗号を組み合わせるのか
鍵の種類ごとに、得意なことと苦手なことがあります。共通鍵暗号(例:AES)は処理が軽く高速ですが、 通信を始める前にクライアントとサーバーが同じ鍵をあらかじめ共有している必要があります。 初対面のクライアントとサーバーが、盗聴される可能性のある経路の上でどうやって同じ鍵を安全に渡すのかが問題です。
公開鍵暗号(例:RSAやECDHEを使った鍵交換)は、この問題を解決できます。 公開鍵で暗号化したものは、対になる秘密鍵でしか復号できないため、公開鍵自体は誰に知られても構いません。 ただし公開鍵暗号は計算量が多く、処理が重いという欠点があります。 Webページの本文をすべて公開鍵暗号でやり取りすると、通信が遅くなってしまいます。
そこでTLSは、2つを役割分担させます。処理が重い公開鍵暗号は、最初の鍵の受け渡しという小さな仕事だけに使い、 鍵さえ安全に渡せてしまえば、あとは処理が軽い共通鍵暗号に切り替えて本文をやり取りする。 これが、TLSハンドシェイクのあとに通信が高速なまま暗号化されている理由です。
証明書とCAが保証していること
証明書には、ドメイン名・サーバーの公開鍵・発行した認証局(CA)の名前・署名などが記載されています。認証局(CA)は、証明書を発行する前に「その証明書を申請した人が、本当にそのドメインの持ち主か」を確認し、 問題がなければ自分の秘密鍵で証明書に署名します。ブラウザは、あらかじめ信頼できるCAの一覧を持っており、 その署名が正しいかどうかを検証します。
ここで誤解しやすい点があります。証明書が保証しているのは、「安全なサイトであること」ではありません。あくまで「たしかに証明書に書かれたドメインの持ち主であること」だけです。 ブラウザの鍵マークは「この通信は暗号化されていて、相手はドメインの持ち主として確認が取れている」ことを示すものであり、 そのサイトが提供する内容が安全である、詐欺目的のサイトではない、ということまでは保証しません。 鍵マークがあっても油断せず、フィッシングサイトの見分け方は別に必要になります。
練習問題(全5問)
選んでから「採点する」を押すと、解説つきで答え合わせができます。
正解:GET
GETはリソースを取得するためのメソッドです。画像やHTMLページの取得のように、サーバー側の状態を変えずに読み取るときに使います。
正解:指定したリソースが見つからない
404 Not Foundは、指定したURLに対応するリソースがサーバー側に存在しないことを示します。「アクセスする権限がない」を意味する403とは別のコードです。
正解:HTTP:80 / HTTPS:443
HTTPは80番ポート、HTTPSは443番ポートを標準で使います。
正解:証明書が信頼できる認証局(CA)の署名を持っているか
クライアントは証明書が信頼できる認証局(CA)によって署名されているかを確認します。これによって、通信相手が証明書に書かれたドメインの持ち主であることを確かめます。
正解:そのドメインの持ち主が、証明書に書かれた相手であること
証明書が保証するのは、あくまで「そのドメインの持ち主が、証明書に記載された相手であること」です。サイトの内容が安全かどうか(フィッシングサイトでないかなど)までは保証しません。