プログラミング初心者がアーキテクトっぽく語る

見苦しい記事も多数あるとは思いますが訂正しつつブログと共に成長していければと思います

TLS

背景

  • HTTPSは以前は暗号化にSSLを利用していた
  • 現在はTLSを利用している
  • 今でもSSLTLSを指して「SSL」と呼ぶことがある
  • TLSRFC 8446(The Transport Layer Security (TLS) Protocol Version 1.3)で規定されている
  • RFC 8446の規定は結構緩いがTLS_RSA_WITH_AES_128_CBC_SHAはmandatoryな点には注意

概要

  • サーバの認証は証明書で行う
  • クライアントの認証を行うこともできる(MTLS)
  • サーバ→クライアントのデータ暗号化にはサーバが生成した共通鍵を使用する
  • クライアント→サーバのデータ暗号化にはクライアントが生成した共通鍵を使用する

共有鍵

  • 通信データ暗号化に使用する「共有鍵」とは証明書の「公開鍵」のことではなくTLS Handshakeで生成する鍵のことである
  • 証明書の「公開鍵」、「秘密鍵」による暗号化、復号化は処理負荷が高く低速なため通信データの暗号化、復号化に適さない
  • このためより軽量な「共有鍵」をTLS Handshakeで生成して通信データの暗号化、復号化に使用する
  • 生成した「共有鍵」を対向装置に送る際には厳重に保護する必要があり、このときだけ 証明書の「公開鍵」、「秘密鍵」で暗号化、復号化する

Cipher Suite

  • TLSでは複数の暗号化、認証技術を組み合わせて使用する
  • これらの注文をアラカルトで受けるのは面倒なのでTLSではCipherSuiteという形でセットメニュー化して管理している

TLS Handshake

TLSではTCP 3 way handshakeの後にTLS Handshakeを行う。

TLS HandshakeではCipherSuite等TLSの条件の合意、証明書によるサーバ認証、暗号用共通鍵の生成と通知が行われる。

以下にTLS Handshakeのシーケンス図を示す。青字のメッセージは暗号化されたメッセージを表す。

f:id:hogehoge666:20200811110707p:plain
TLS Handshake

1. ClientHello

  • クライアントはサーバに対して、サポートしているTLSバージョン、利用可能なCipherSuite、ランダム値を送る。

2. ServerHello

  • サーバはClientHelloのリストから選択した条件とランダム値をクライアントに通知する。

3. Certificate

  • サーバは自分の証明書を送信する。

4. ServerHelloDone

  • サーバはHelloメッセージフェーズが終了したことを通知する。

5. ClientKeyExchange

  • クライアントはサーバーの証明書を検証する。
  • Premaster secretを生成して送る。

6. ChangeCipherSpec

  • クライアントはPremaster secretと手順1,2のランダム値からMaster Secretを生成する。
  • 次にMaster Secretからクライアントが暗号化に使用するMACシークレット、セッション キーを生成してサーバへ通知する。

7. Finished

  • クライアントはFinished メッセージをサーバに送る。
  • これは最初の暗号化されて送られるメッセージである。

8. ChangeCipherSpec

  • サーバはクライアントと同じ手順でMaster Secret、MACシークレット、セッション キーを生成してクライアントへ通知する。
  • これらの値はクライアントと同じになる。

9. Finished

  • サーバーはFinished メッセージをクライアントに送る。
  • これ以降のクライアント・サーバ間のデータ通信は暗号化される