SSL/TLSについて知識が曖昧だったのでメモ
SSL/TLSとは
TLS/SSL は、インターネット上での通信を保護するための暗号化プロトコル
役割
- 通信内容の暗号化
- 送受信されるデータが暗号化されることで、盗聴や改ざんから保護される
- サーバー認証
- サーバの証明書を検証することで、偽装されたサーバとの通信を防ぎ、なりすまし攻撃から保護される
処理の流れ
- クライアントが Web サーバに HTTPS でアクセスすると、クライアントと Web サーバ間で TLS/SSL ハンドシェイクと呼ばれるプロセスが行われる
- ハンドシェイクでは、以下の手順が行われる
- クライアントは、利用可能な暗号化アルゴリズムとハッシュ関数のリストを送信
- サーバは、クライアントと共通の暗号化アルゴリズムとハッシュ関数を選択
- サーバは、証明書を送信し、クライアントはその有効性を検証を実施
- クライアントとサーバは、共有秘密鍵を生成
- ハンドシェイクが完了すると、通信内容は共有秘密鍵を使って暗号化され、安全に送受信される
勘違いしがちなところ
NginxやApacheはSSL/TLSの設定や管理をしているのみで、実際にSSL/TLSを動かしているのではない。
動作確認
HTTPS通信において、サーバーはクライアントに証明書の情報を返却する。
実際にAPIを実行して、レスポンスに証明書の結果が含まれることを確認
curl -vS https://www.example.com
-v: 詳細な情報を表示
-S: ヘッダーのみを表示
* Connected to www.example.com (93.184.215.14) port 443 (#0)
* ALPN: 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):
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: C=US; ST=California; L=Los Angeles; O=Internet�Corporation�for�Assigned�Names�and�Numbers; CN=www.example.org
* start date: Jan 30 00:00:00 2024 GMT
* expire date: Mar 1 23:59:59 2025 GMT
* subjectAltName: host "www.example.com" matched cert's "www.example.com"
* issuer: C=US; O=DigiCert Inc; CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
* SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: www.example.com]
* h2 [:path: /]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x12e811400)
> GET / HTTP/2
> Host: www.example.com
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 200
< age: 540655
< cache-control: max-age=604800
< content-type: text/html; charset=UTF-8
< date: Thu, 02 May 2024 00:52:14 GMT
< etag: "3147526947+ident"
< expires: Thu, 09 May 2024 00:52:14 GMT
< last-modified: Thu, 17 Oct 2019 07:18:26 GMT
< server: ECAcc (sac/2533)
< vary: Accept-Encoding
< x-cache: HIT
< content-length: 1256
...
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
ハンドシェイクプロセスのログがある!
* SSL certificate verify ok.
SSL認証が通っていることが確認できた!
実際にコマンドを実行してみることで、ハンドシェイクが確立→認証→リクエストの送受信されることが理解できた。