TLSは暗号、認証、改ざん検出の機能があり、ネットワークセキュリティとしては必須技術です。
本書ではTLSの仕組みを解説し、理解を深めていきます。
TLSはいくつかバージョンがありますが、本書はTLS1.3に特化した説明となっています。
SSLとの関係
SSLはよくTLS と一緒に出てきますが、SSLはTLSの前身であり今はあまり使われないです。
SSLは1995年にNetscapeが開発したインターネット通信を暗号化する仕組みです。
後継であるTLSはIETFによる標準化がされています。
サーバ証明書
TLSを使用して通信での認証を行うためにはサーバ証明書が必要です。
サーバ証明書は、このサーバは本物だとと証明するための身分証明書であり、これを発行元である認証局(CA)が証明する仕組みとなっています。
(サーバ証明書は「SSLサーバ証明書」や「SSL証明書」などと言われることも多い。)
サーバ証明書は事前にサーバー管理者が認証局(CA)から取得してサーバーにインストールしておきます。

サーバ証明書の発行とCAAレコード
サーバ証明書は、サーバの管理者が認証局(CA)という第三機関に依頼して発行してもらいます。
サーバ証明書はドメイン名(例:「example.com」)に対して発行されます。
サーバ証明書の発行は正規のドメイン名所有者ではない第三者による不正な証明書の発行がされてしまう可能性もあります。
そこでDNSサーバのDNSレコードに予め証明書を発行することを許可する認証局を指定しておきます。
これをCAAレコードといいます。
DNSのCAAレコードを使うことで、どのCAに証明書発行を許可するかを制限できるのです。

TLSハンドシェイク
TLSはクライアントとサーバとが通信をするときに様々なやり取りをします。
ハンドシェイク「握手」という意味の英単語で、TLSではクライアントとサーバがお互いの状態や設定を確認して安定した接続を確立するための握手に例えられています。
接続開始時の大まかな流れ
TLSは大まかに次の2ステップの流れになっています。
【STEP1】データの暗号化に使う共通鍵を生成(鍵交換)
【STEP2】サーバ証明書で正しいサーバであることの確認
クライアント認証はオプション(省略可)とされていますので、今回の例では、サーバー認証だけを行っています。
TLS1.3に特化した説明となっています。
【STEP1】データの暗号化に使う共通鍵を生成(鍵交換)
■Client Helloメッセージ
最初にクライアントは次の処理をします。
- 秘密鍵を生成します。((EC)DHE用の一時的な値)
- 秘密鍵(ランダムな値)と、両者で共有する数字(事前に規格で決まっている)をもとに「key share」というパラメータを生成します。
※key shareは鍵交換に使用するための公開値です。 - 対応可能な暗号スイート(暗号やハッシュ規格)、対応な鍵交換規格の候補、先ほど生成した公開鍵をサーバへ送付します。

■Server Helloメッセージ
サーバはクライアントからの送信(Client Hello)を受け取った後、次の処理をします。
①と②はクライアントと同じですが、秘密鍵と公開鍵の値はクライアントと異なります。
- 秘密鍵(ランダムな値)を生成します。
- 秘密鍵(ランダムな値)と、両者で共有する数字(事前に規格で決まっている)をもとに「key share」というパラメータを生成します。
- 選択した暗号スイート、鍵交換規格の候補を選んだ結果と、先ほど生成した公開鍵をサーバへ送付します。

■共通鍵を生成
クライアントとサーバはそれぞれ受け取ったkey share、両者で共有する数字、自分の秘密鍵の3つを使って、共通鍵を生成します。
この共通鍵は両者で同じ値になります。

クライアントとサーバで今回の通信で使う共通の鍵が共有できたので、この後の通信はこの鍵を使って暗号化がされます。
TLS1.3の暗号スイートはAEAD (Authenticated Encryption with Associated Data) とハッシュアルゴリズムの組みで構成されています。
■鍵交換方式:ECDHE
TLS1.3での鍵交換は一般的にECDHEが良く使われます。
ECDHEは楕円曲線暗号を使用することで、短かい鍵長で高い安全性を実現し、処理速度が速いのが特徴です。
タイムアウト発生後の再開用のキー(PSK)交換は省略しています。
この後の「PSKによるセッション再開」で説明します。
【STEP2】サーバ証明書で正しいサーバであることの確認
■Certificate
サーバの公開鍵証明書が正当なものか確認します。
サーバはサーバ証明書(公開鍵証明書)をクライアントへ送り、クライアントはCAの公開鍵で正当性を確認します。
ここで使われている技術はPKI(公開鍵基盤)による確認となります。

■Certificate Verifyメッセージ
サーバが公開鍵に対する秘密鍵を確かに持っていることを確認するために、サーバは署名をクライアントへ送り、クライアントはサーバの公開鍵を使って署名を検証します。
- サーバは、ハンドシェイク全体のこれまでのやり取りのハッシュ値を計算
- そのハッシュ値に対して サーバ証明書に対応する秘密鍵で署名 を作成
- その署名を Certificate Verify メッセージ としてクライアントへ送る
- クライアントはサーバ証明書の「公開鍵」でCertificate Verify メッセージを復号し、これまでのやり取りのハッシュ値と一致することを確認

PSKによるセッション再開
クライアントとサーバ間でタイムアウトが発生した場合、セッションを再開しますが、また1から鍵交換、サーバ認証全てをやり直すのではなく、予め共有してあるPSKという再開用のキーを使って速やかに再開できます
PSKはSession Ticketという情報の中に格納され、Session Ticketは暗号化してクライアント側で保持するので安全です。
Session Ticketはサーバが予め用意しているTicket Keyという鍵で複合化して使います。
最初の接続時(新しいフルハンドシェイク)
- クライアントがClientHelloを送信
- サーバがフルハンドシェイクを完了後、セッション再開に必要な情報(PSK、識別子、有効期限など)をSession Ticketとして生成
Ticket KeyでSession Ticketを暗号化してクライアントへ送信
※Session Ticketを暗号する際はAEAD(認証付き暗号化)を使用する
※サーバはクライアントへ送信した後、Session Ticketは削除する。(サーバー側のリソースが消費を防ぐため) - クライアントはSession Ticket(暗号化されたまま)を保持しておく

PSKを使ったセッション再開
- クライアントがSession Ticket(暗号化されたまま)、ECDHE鍵共有(key_share extension)を含めてサーバへ送信
- サーバは受け取ったSession TicketをTicket Keyで復号し、PSKなどの情報を取り出して検証
- サーバはクライアントのECDHE鍵共有(key_share extension)とサーバのECDHE鍵共有(key_share extension)からトラフィックキーを生成
- サーバは、サーバ側の鍵共有(ECDHE)を返す
- クライアントは受信した鍵共有(ECDHE)から暗号化通信に必要な鍵(トラフィックキー)を算出する。
- クライアントはFinishedメッセージを送る
- サーバはFinishedメッセージを送る
- 以降はトラフィックキーで暗号化してやり取り

TLS1.3の暗号スイート
TLSには、予め通信に使う暗号アルゴリズムを組み合わせた「暗号スイート」という言われる技術の組み合わせのセットがあります。
TLS 1.2以前では、①暗号化アルゴリズム、②鍵交換方式、③認証方式、④ハッシュ関数の4つの組み合わせで暗号スイートが定義されていました。
しかし、TLS 1.3では、暗号スイートは「認証付き暗号(AEAD)+ハッシュ関数」の2つの構成となり、「鍵交換方式」と「認証方式」はプロトコル側で管理され、暗号スイートからは独立しました。

TLS 1.3で定義されている暗号スイートは、以下の5種類です。
- TLS_AES_128_GCM_SHA256
高速かつ広く使われるAES 128bit鍵の認証付き暗号方式(GCM)とSHA-256を組み合わせたもの。 - TLS_AES_256_GCM_SHA384
AES 256bit鍵でより強力な暗号化を行い、GCMとSHA-384を組み合わせた高セキュリティの方式。 - TLS_CHACHA20_POLY1305_SHA256
モバイルやIoT向けに高速・軽量なChaCha20とPoly1305の認証付き暗号、SHA-256を組み合わせた方式。 - TLS_AES_128_CCM_SHA256
リソース制約環境向けのAES 128bit鍵の認証付き暗号方式(CCM)とSHA-256の組み合わせ。 - TLS_AES_128_CCM_8_SHA256
MAC長が8バイトと短く、IoTなど帯域やリソースが限られる用途向けのAES 128bit鍵CCM方式とSHA-256の組み合わせ。
利用環境やセキュリティ要件に応じて、これらの暗号スイートを選択できるようになっています。


コメント