LoginSignup
1
0

SSL/TLSについて

Posted at

はじめに

Isuconに出場してみて、全くHTTPSSSL/TLSについて理解できていないことに気づいたので、まとめてみます。

SSL/TLSとは

通信を暗号化するためのプロトコルです。
HTTPS通信はSSL/TLSによって実現されています。
かつてはSSLが使われていましたが、現在では非推奨になっており、主にTLSが使われています。
その名残で、現在でもSSLSSL/TLSなどといったような参照のされ方をすることがあります。

SSLNetscape社によって管理されていましたが、TLSIETFによって管理されています。

現在ではTLS1.0, TLS1.1は非推奨になっており、TLS1.2, TLS1.3のいずれかを使う必要があります。(RFC 8996)

TLS通信の手順

主に「サーバ側の事前準備」、「TLSハンドシェイク」、「暗号化して通信」の3つの段階を踏みます。

サーバ側の事前準備

TLS通信を実現するにあたって、サーバ側は「サーバ証明書」を用意する必要があります。
この証明書によって、サーバの信頼性を保証します。
これには、サイトの主体者、証明書の発行者、有効期間、公開鍵などが含まれます。

Chromeだと、アドレスバーの左側のボタン -> 「この接続は保護されています」 -> 「証明書は有効です」からそのサイトの証明書を確認することができます。

スクリーンショット 2024-03-14 23.43.37.png

証明書には、発行者のデジタル署名がついており、その発行者の証明書を取得することで、署名を検証することができます。
これはその発行者の証明書も同じで、木構造になっており、自己認証をすることができるRoot認証局に辿り着くまではこれを繰り返します。

こちらの記事が大変わかりやすかったです。

OSには、この信頼できるRoot認証局の証明書の一覧が入っているため、ここで整合性を確かめることができます。(/etc/ssl/cert.pemなどにあるかと思います。)

TLSハンドシェイク

TLSハンドシェイクでどんなことが行われているかは、curlverboseオプションで確認することができます。
(※ TLS1.2の例)

% curl -v https://qiita.com
*   Trying 13.114.185.91:443...
* Connected to qiita.com (13.114.185.91) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=qiita.com
*  start date: Nov  4 00:00:00 2023 GMT
*  expire date: Dec  2 23:59:59 2024 GMT
*  subjectAltName: host "qiita.com" matched cert's "qiita.com"
*  issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M03
*  SSL certificate verify ok.

Client Hello (Client -> Server)

まず、client側からClient Helloを送信します。
ここでは、clientが対応している

などを格納して送信します。

スクリーンショット 2024-03-15 2.44.12.png

Server Hello (Client <- Server)

サーバ側では、Client Helloに含まれる情報と自身の設定を照らし合わせて、確定した情報をServer Helloとして返します。
ここでは、

  • 使用することになった暗号スイート
  • 使用するアプリケーション層のプロトコル
  • ランダム文字列

などが格納されています。

スクリーンショット 2024-03-15 2.52.48.png

Certificate (Client <- Server)

サーバ側から「サーバ証明書」を送信します。
サーバ証明書とその上の階層の中間証明書が含まれています。

スクリーンショット 2024-03-15 3.09.39.png

Server Key Exchange (Client <- Server)

TLSによる暗号通信は、暗号化と復号が同じ鍵で行われる「共通鍵暗号方式」が採用されています。
なので共通鍵を共有する必要があり、ここで使われるのが暗号スイートです。

特定のアルゴリズムを使うことによって、第3者に盗み見られることなく共通鍵を共有することができるようになります。
そのアルゴリズムを実現するために必要なパラメータが、このSecret Key Exchangeで送信されます。

スクリーンショット 2024-03-15 4.43.32.png

Server finished ・ Server Hello Done (Client <- Server)

Server Helloから始まった、サーバからの一連の情報の送信が終わったことを示す情報を送信します。

スクリーンショット 2024-03-15 4.45.54.png

Client Key Exchange (Client -> Server)

RSAで暗号化されている場合、client側で共通鍵を生成し、サーバから送信されている公開鍵で暗号化して送信します。

DH鍵交換アルゴリズムの場合は、どちらか一方が完全な共通鍵を作るのではなく、どちらともが共通鍵の要素を作り、お互いに交換し、計算することで共通の鍵を生成します。
Client Key Exchangeでは、サーバ側が共通鍵を生成するために必要なパラメータをクライアント側から送信します。

スクリーンショット 2024-03-15 5.40.21.png

Change Cipher Spec ・ Finished (Client -> Server)

client側から、暗号通信をするにあたって必要な情報が揃ったことを示す情報を送信します。

スクリーンショット 2024-03-15 5.53.17.png

Change Cipher Spec ・ Finished (Client <- Server)

server側からも、暗号通信をするにあたって必要な情報が揃ったことを示す情報を送信します。

スクリーンショット 2024-03-15 5.54.06.png

暗号化して通信

TLSハンドシェイクによって、サーバとクライアントのみが知る共通鍵が出来上がったので、以降はこれで、暗号化/復号をして通信をします。

参考

1
0
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
1
0