26
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTTPSの仕組み — TLSハンドシェイクを順番に追う

26
Posted at

はじめに

ブラウザでWebサイトを開くとき、URLの先頭に https:// と書かれていたり、鍵のアイコンが表示されていたりしますよね。

「鍵マークがついてるから安全」というのは知っていても、なぜ安全なのかを説明できる人は意外と少ないと思います。

この記事では、HTTPSの仕組みを初心者でもわかるように、TLSハンドシェイクの流れを順番に追いながら解説します。


HTTPとHTTPSの違い

まず基本から整理します。

HTTP HTTPS
暗号化 なし あり(TLS)
盗聴リスク 高い 低い
改ざんリスク 高い 低い
なりすましリスク 高い 低い
ポート番号 80 443

HTTPは通信内容が平文(そのまま読める状態) で流れます。つまり、悪意のある第三者が通信を傍受すると、パスワードやクレジットカード番号がそのまま見えてしまいます。

HTTPSはこの問題を解決するために、TLS(Transport Layer Security) という仕組みで通信を暗号化します。


SSLとTLSの違い

「SSL」という言葉を聞いたことがある人も多いと思います。

  • SSL(Secure Sockets Layer):古い暗号化プロトコル。現在は脆弱性があり使用禁止
  • TLS(Transport Layer Security):SSLの後継。現在はこちらが使われている

現在はTLS 1.2 / TLS 1.3が主流です。「SSL証明書」という呼び名が残っていますが、実際にはTLSを使っています。


TLSハンドシェイクとは?

HTTPSで通信を始めるとき、最初にハンドシェイク(握手) と呼ばれる手続きが行われます。

このハンドシェイクでは、以下のことを決めます。

  • お互いの身元確認(サーバーが本物かどうか)
  • 暗号化に使う方式の決定
  • 暗号化に使う鍵の共有

では、順番に追っていきましょう。


TLSハンドシェイクの流れ

クライアント(ブラウザ)              サーバー
        |                                |
        |  ① ClientHello                 |
        |-----------------------------→  |
        |                                |
        |  ② ServerHello + 証明書         |
        |  ←-----------------------------|
        |                                |
        |  ③ 証明書の検証(クライアント側)  |
        |                                |
        |  ④ 鍵交換                       |
        |-----------------------------→  |
        |                                |
        |  ⑤ 暗号化通信スタート            |
        |  ←--------------------------→  |

① ClientHello(クライアントが「こんにちは」)

ブラウザがサーバーに接続を開始するとき、まずClientHelloというメッセージを送ります。

このメッセージには以下の情報が含まれます。

  • 対応しているTLSのバージョン(例:TLS 1.3)
  • 対応している暗号化方式の一覧(例:AES, ChaCha20)
  • ランダムな数値(後で鍵の生成に使う)

イメージ: 「私はこんな暗号方式が使えます。何が使えますか?」とサーバーに聞いている状態


② ServerHello + 証明書の送付

サーバーはClientHelloを受け取ったら、ServerHelloを返します。

このメッセージには以下の情報が含まれます。

  • 選択した暗号化方式(クライアントが提示した中から選ぶ)
  • ランダムな数値(後で鍵の生成に使う)
  • サーバー証明書(身元を証明する書類)

サーバー証明書には、以下の情報が含まれています。

  • サーバーのドメイン名(例:example.com
  • 証明書の有効期限
  • 発行した認証局(CA)の情報
  • 公開鍵

イメージ: 「こちらはこの暗号方式でいきましょう。私の身分証明書もどうぞ」


③ 証明書の検証(クライアント側)

ブラウザはサーバーから受け取った証明書が本物かどうかを確認します。

確認する内容は主に以下の3点です。

  1. 信頼できる認証局(CA)が発行したか?
    ブラウザには「信頼できる認証局リスト」があらかじめ入っています。そのリストに含まれるCAが署名した証明書かどうか確認します。

  2. 証明書の有効期限が切れていないか?

  3. アクセスしているドメインと証明書のドメインが一致しているか?

イメージ: 「この身分証明書は、信頼できる機関が発行したものか確認しよう」

ここで証明書が不正だと判断されると、ブラウザは警告画面を表示します(「この接続は安全ではありません」といった画面)。


④ 鍵交換(セッション鍵の生成)

証明書の確認ができたら、次に暗号化通信で使う鍵(セッション鍵) を生成します。

TLS 1.3ではECDHE(楕円曲線ディフィー・ヘルマン鍵交換) という方式が使われます。

ポイントは、鍵そのものをネットワーク上に流さないという点です。クライアントとサーバーがそれぞれ計算することで、同じ鍵を導き出します。

イメージ: 「答えを教えあわなくても、同じ答えにたどり着ける計算方法がある」という仕組みです。


⑤ 暗号化通信スタート

セッション鍵が共有されたら、あとはその鍵を使って通信内容を暗号化・復号しながらやり取りします。

このセッション鍵はその通信限りで使われ、接続が切れると破棄されます。


なぜ3つの脅威を防げるのか

TLSが防いでいる脅威を整理します。

脅威 TLSでの対策
盗聴(通信内容を見られる) セッション鍵で暗号化しているので読めない
改ざん(通信内容を書き換えられる) MAC(メッセージ認証コード)で検知できる
なりすまし(偽サーバーへの誘導) 証明書の検証でサーバーの身元を確認

まとめ

HTTPSのTLSハンドシェイクをまとめると次の通りです。

  1. ClientHello:クライアントが使える暗号方式を伝える
  2. ServerHello+証明書:サーバーが暗号方式を選び、身分証明書を渡す
  3. 証明書の検証:ブラウザがサーバーの身元を確認する
  4. 鍵交換:暗号化通信に使うセッション鍵を生成する
  5. 暗号化通信スタート:以降はすべて暗号化してやり取り
26
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?