SSLについて

日経クロステックさんの図解 があまりにも分かりやすかったので、ほぼすべて引用(盗用)させて頂きました🙇‍♂️)

SSL とは

  • SSLが持つ機能は大きく二つ
    • 「データの暗号化」
    • 「通信相手が信頼できることの確認」(認証)

Lesson1:アプリ同士のやりとりを暗号化、相手が信頼できるかも確かめる | 日経クロステック(xTECH)

相手認証

  • 大事なデータを送るときには、通信相手のサーバーがなりすまされた相手ではなく、信頼できる相手かどうかを確かめる必要も出てくる
  • SSL には、通信相手が信頼のおけるサーバーかどうかを確かめる機能も備わっている
    • クライアントがサーバーから「サーバー証明書」と呼ばれる情報を受け取る
    • そのサーバー証明書を検証することで、通信相手のサーバーが信頼できるかどうかを判断する
  • SSL はアプリケーションの種類は問わない汎用的なプロトコル
    • HTTP 以外にもメールや FTP といったアプリケーションのデータを暗号化することも可能

SSL の位置関係

TLS とは

  • SSL と TLS の動作と機能はほぼ同じ
    • SSL は元々、ネットスケープが開発した独自仕様のプロトコルだった
    • TLS は Web アクセスの普及とともに、SSL をベースとして登場した標準技術のこと

SSL / TLS (Transport Layer Security)

  • SSL
    • 2015年6月、RFC 7568によってSSL 3.0の使用は禁止された
  • TLS
    • 2022年3月時点は、TLS 1.3 が最新

「SSL は、使うべきではない。」

  • 正確には SSL の使用は禁止され、現在は TLS を使っている状態(*多くの主要ブラウザで「SSL3.0」が無効となっている)
  • 実際は「TLS」を利用しているが、呼び名として「SSL」を使っている
    • TLS と言っても馴染みがなく伝わりにくい
    • SSL と言った方が伝わりやすい
  • 現在では「TLS のことも含めて SSL と呼ぶ」または「SSL/TLS」「TLS/SSL」のような併記で使われる事が多い

(TLS は)(特に区別する場合を除いて)SSL (Secure Sockets Layer) と呼ばれることも多い。これは、TLSの元になったプロトコルがSSLであり、そのSSLという名称が広く普及していることによる。

Transport Layer Security - Wikipedia

暗号通信で使う「鍵」

Lesson2:二つの暗号方式を組み合わせて、安全かつ高速に通信をする | 日経クロステック(xTECH)

  • SSL は、二つの暗号方式を組み合わせて利用している
    • 「共通鍵暗号」
    • 「公開鍵暗号」

共通鍵暗号

  • 特徴
    • 暗号化と復号に同じ鍵(共通鍵)を使う暗号方式
    • 暗号化と復号の処理が軽い
    • 実際にアプリケーション同士でやりとりするデータの暗号化/復号に、この共通鍵暗号を利用する
  • 問題点
    • 送信側と受信側の両者が、あらかじめ誰にも知られていない同じ鍵を持っていなければいけない
      • あらかじめ通信相手を特定していないインターネットの通信で、両者が通信前に同じ鍵を持つことは不可能
    • とはいえ、鍵をそのままインターネットで送ると、肝心の鍵が他人に盗まれる恐れがあるので危険

公開鍵暗号

  • 公開鍵暗号は、公開鍵と秘密鍵と呼ばれるペアの鍵を使う方式
  • 片方の鍵で暗号化したデータは、ペアとなっているもう片方の鍵でしか復号できない
  • 片方の鍵をインターネットで公開しても、もう片方の鍵を秘密にしておけば、目的の相手(公開鍵のペアとなっている秘密鍵を持つ相手)だけに安全にデータを送れる

SSL 通信の概要

前処理:共通鍵の共有

  1. クライアント側が SSL 通信を要求する
  2. サーバー側は「自身の公開鍵が入った証明書」をクライアント側に送る
  3. クライアント側は受け取った「公開鍵」を暗号化して「共通鍵」に変換し、サーバー側に送り返す(公開鍵暗号
  4. サーバー側は受け取った「暗号化された共通鍵」を「秘密鍵」を使って復号する
  5. 以降は双方で「共通鍵」を使った通信を行うため、高速にデータを暗号化/復号することができるようになる

共通鍵を使った暗号通信を始めるまでのやりとり(共通鍵の共有)

Lesson3:実際の通信はどうなってる?やりとりの詳細を見てみよう | 日経クロステック(xTECH)

  • SSLは、大きく二つの仕様で成り立っている
    • レコード・プロトコル
      • メッセージのフォーマット
    • ハンドシェーク・プロトコル
      • そのメッセージを使って暗号通信を実現するまでの手順

レコード

- SSLで運ぶメッセージは「レコード」と呼ばれる
- SSLのレコードは、大きく「ヘッダー部分」と「データ部分」に分かれている
- **レコード**
    - **ヘッダー部分**
    - データの種類(タイプ)、バージョン(SSLかTLSか)、データ長の情報が入っている
    - **データ部分**
    - ハンドシェーク・プロトコルのメッセージや、暗号通信時の暗号化データが入っている

ハンドシェーク・プロトコル

  • 暗号通信をするにあたって必要な情報をやりとりする際に使われる
  • クライアントとサーバーの両者が、メッセージの種類を区別できるようになっている
  • 個々のメッセージは、「ClientHello」や「ServerHello」といった種類(タイプ)が決まっている

一般的なSSLのやりとりの様子

実際のSSL通信では、共通鍵を直接やりとりするのではなく、共通鍵の基となるプレマスタ・シークレットをやりとりして、そこからクライアントとサーバーがお互いに共通鍵を生成するしくみになっている。

  1. SSLのやりとりは、クライアントがサーバーに、暗号通信で使う暗号方式などを提案することから始まる
  2. サーバーは、提案のあった方式から適切なものを一つ選んで返答する(ここまでで、暗号通信時に使う暗号方式を決める)
  3. サーバーは、クライアントに Certificate メッセージを使ってサーバー証明書を送る
  4. 証明書の情報を送り終えたら、そのことを知らせる
  5. クライアントは、(3)で入手したサーバー証明書からサーバーの公開鍵を取り出し、この公開鍵を使って暗号通信に使う共通鍵の基になる秘密の値(プレマスタ・シークレット)を暗号化して送信する
    → これが ClientKeyExchange メッセージ
    → サーバーは、この暗号化したデータを自身の秘密鍵で復号すると、プレマスタ・シークレットが出てくる。この時点で両者は、共通鍵の基となるプレマスタ・シークレットを共有できた
  6. これまで決めた暗号方式の採用を宣言
  7. ハンドシェークの終了をサーバーに知らせる
  8. 暗号方式の採用を宣言
  9. ハンドシェークの終了をクライアントに知らせる

サーバー証明書

  • サーバー証明書は、サーバーの管理者が「認証局」と呼ばれる組織に申請して発行してもらう
  • サーバー証明書には、サーバー運営者の組織名、認証局の組織名、証明書の有効期限などの情報が書き込まれている
    • このサーバー証明書の中に、サーバーの公開鍵も含まれている
  • さらにサーバー証明書には認証局の署名が付いている
    • 署名とは、証明書の内容をハッシュした値を、認証局の秘密鍵で暗号化したデータのこと

ハッシュ値とは

  • 元データに対して生成された適当な値(適当に見える値)のこと
  • 何を入れるとどんな値が返ってくるか、入れたものからは分からない
  • ただし、同じ物を入れれば必ず同じ値が返ってくる
    • 何回入れても必ず同じ値が返ってくる

証明書の信頼性(サーバー認証)

  • サーバー証明書は厳密には、サーバーではなく認証局が発行している
  • さらにサーバー証明書と一緒に、署名を施した認証局の証明書もクライアントに送られている
    • もし、その認証局が他の認証局から署名を受けている場合は、さらにその署名を受けた認証局の証明書も付けて送られる
  • こうして、最終的には一番上位に位置する「ルート認証局」と呼ばれる認証局の証明書が必ず送られてくる
  • そこでまずクライアントは、「そのルート認証局が信頼できるか」を確認する
  • パソコンにはあらかじめ、信頼できるルート認証局の証明書(自己証明書)が複数インストールされている
  • クライアントは、そのあらかじめパソコンに入っている証明書と、サーバーから受信した証明書が一致するかを確認する
  • 一致したら受信した証明書は信頼できると判断する

ルート証明書が信頼できてからの流れ

  • ルート証明書が信頼できたら、ルート証明書の中にある公開鍵を使って、ルート認証局から署名を受けた証明書(サーバー証明書)を検証する
  • 具体的には以下が一致するかどうかを確かめる
    • 「署名をルート認証局の公開鍵で復号したデータ」
    • 「サーバー証明書のハッシュ値」
  • 一致すれば、そのサーバー証明書は、確かにルート認証局から署名を受けた信頼できるサーバー証明書であると判断する
  • サーバー証明書が信頼できたら、その中にある公開鍵も信頼できることになる
  • ようやくここでクライアントはこの公開鍵を使って、SSL 通信を実行する

SSL/TLS の安全性の診断

まとめ

  • SSL を利用していると思っていたが、実は TLS を利用していた(多くの主要ブラウザで「SSL3.0」が無効になった)(SSL という呼び名が名残として残っているだけだった)
  • 現在では「TLS のことも含めて SSL と呼ぶ」または「SSL/TLS」「TLS/SSL」のような併記で使われる事が多い

公開鍵・秘密鍵から共通鍵を生成するまで

  • 重要な点は「実際に情報のやり取りを行う前の段階(共通鍵の生成:前処理)」であることがわかった
    • クライアントはサーバーから受け取った公開鍵を使って、(他者が介在しない独立した環境の中で)「プレマスタ・シークレット(秘密の値)」を生成する → さらにこれを基に共通鍵を独自に生成する
    • さらに、暗号化された「プレマスタ・シークレット(秘密の値)」をサーバーに送る
      • この過程で通信を傍受されても「プレマスタ・シークレット(秘密の値)」から共通鍵を生成できるのは、クライアント or 秘密鍵を持つ者のみ
    • サーバーはクライアントから受け取った「プレマスタ・シークレット(秘密の値)」を、当初の公開鍵とペアになった秘密鍵を使って復号 → 共通鍵を生成する
      • ポイントは、鍵を直接やり取りするのではなく、「鍵の基となる値」を暗号化してやり取りし、双方がそれを基に共通鍵を生成することで共通鍵の共有を実現する点にある
    • 以降は双方で生成した共通鍵を使って暗号化された通信が実現する

サーバー認証

  • サーバーはサーバー証明書を自身で発行するのではなく、認証局に申請して発行してもらう
  • 証明書は「サーバー証明書」と「認証局の自己証明書」があり、最上流の認証局のことを「ルート認証局」と呼ぶ
  • パソコンにはもともと信頼できる証明書が入っており、SSL 通信で送られてくる「ルート認証局の自己証明書」がこれと一致するか検証する
  • 次に以下の2点が合致するか検証する
    1. 「サーバー証明書の(暗号化された)署名」を「ルート認証局の自己証明書の中にある公開鍵」で復号した値
    2. 「サーバー証明書のデータ」をハッシュしたハッシュ値
  • これが一致することで信頼できる証明書と判断し、証明書の中の公開鍵を使い、以降の SSL/TLS 通信を行う