SSL/TLS(Secure Socket Layer/Transport Layer Security)

アプリケーションデータを暗号化するプロトコル。TLSはSSLをバージョンアップしたもの(ここからSSLは同時にTLSも含む)

図:SSL/TSLで情報を守る

どのバージョンで接続するかはWebブラウザとWebサーバーの対応状況と設定次第。使用するバージョンは暗号化通信に先立って行われるSSLハンドシェイクによって決定される。

図:SSLのバージョン

以降、2023年現在世の中に広く普及しているTLS1.2について深堀りする。

SSLが使用している技術

SSLで防ぐことができる脅威

なりすまし改ざん盗聴という3つの脅威に対抗している。

暗号化で盗聴を防ぐ

暗号化は決められたルール(暗号化アルゴリズム)に基づいてデータを変換する技術。暗号化によって第三者がデータを盗み見る「盗聴」を防止する。

図:暗号化で盗聴を防ぐ

ハッシュ化で改ざんを防ぐ

ハッシュ化は不定長のデータから決められた計算(ハッシュ化アルゴリズム)に基づいて固定長のデータ(ハッシュ値)を生成する技術。データが変わるとハッシュ値も変わる。これを利用して第三者がデータを書き換える「改ざん」を検知できる。SSLではデータが改ざんされていないかどうかを確認するためにデータとハッシュ値を合わせて送信する。それを受け取った端末はデータから計算して得たハッシュ値と、添付されているハッシュ値を比較する。ハッシュ値が同じなら改ざんされていないことになる。

図:ハッシュ化で改ざんを防ぐ

デジタル証明でなりすましを防ぐ

デジタル証明書はインターネット上にいるほかの端末に対して「私は本物です!」と証明するためのファイル。デジタル証明書に含まれる情報をもとに、通信相手の身元を確認することができ「なりすまし」を防止できる。SSLではアプリケーションデータを送受信するのに先立って、「あなたの情報をください」とお願いする。受け取ったデジタル証明書をもとに、認証局によって認められた信頼できる相手かを確認する。

デジタル証明書が本物かどうかは「認証局(CA、Certification Authority)」と呼ばれる信頼できる第三者の「デジタル署名」によって判断する。デジタル署名は簡単に言うとデジタル証明書に対するお墨付きのようなもの。デジタル証明書はデジサート社やセコムトラストシステムズ社などの認証局からデジタル署名とうお墨付きをもらって初めて世の中に本物と認められる。

図:デジタル証明書でなりすましを防ぐ

SSLを支える技術

SSLは通信を暗号化する暗号化アルゴリズム、暗号化のために必要な鍵を共有する鍵交換アルゴリズム、通信相手を認証するデジタル署名アルゴリズム、通信データを認証するメッセージ認証アルゴリズムとう4つの技術を組み合わせて使用することにより、セキュリティの向上を図っている。

暗号化アルゴリズム

SSLの暗号化技術には、データを暗号化するための暗号化鍵と、暗号化を解く(復号する)ための復号鍵が必要になる。SSLはこの暗号化鍵と複合鍵に同じ鍵(共通鍵)を使用する「共通鍵暗号方式」を使用してアプリケーションデータを保護している。

共通鍵暗号方式にはストリーム暗号方式ブロック暗号方式の2種類がある。ストリーム暗号方式は1ビットごと、あるいは1バイトごとに暗号化処理を行う。代表的なストリーム暗号化アルゴリズムには「ChaCha20-Poly1305」がある。ブロック暗号化方式は一定のビット数ごと(ブロック)に区切って、ブロックごとに暗号化処理を行う。代表的なブロック暗号化アルゴリズムには、「AES-CBC(Advanced Encryption Standard-Cipher Block Chaining)」などがある。

図:共通鍵暗号方式では暗号化と複合に同じ鍵を使用する

共通鍵暗号方式は仕組みが単純明快なので、暗号化処理も複合処理も高速で、大きな処理負荷もかからない。しかし暗号化と複合に使用する共通鍵を何らかの形で共有する必要があるとう致命的な弱点を抱えている。また、暗号化鍵と複合鍵が同じものなので、その鍵を誰かに入手されてしまったらその時点でアウト。お互いで共有する鍵をどうやって開いてに渡す(配送する)のか。この鍵配送問題を別の仕組みでクリアする必要がある。

鍵交換アルゴリズム

前述のとおり、鍵配送問題は共通鍵暗号方式を使用する限り避けることができないセキュリティ上の課題。そこでSSLでは共通鍵を共有するために「DHE(Diffie-Hellman Ephemeral)や「ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)」といった鍵交換アルゴリズムを使用する。これらの鍵交換アルゴリズムを支えているのが公開鍵秘密鍵。公開鍵はその名の通りみんなに公開してよい鍵、秘密鍵はみんなには秘密にしておかなくてはいけない鍵。この2つの鍵は鍵ペアと呼ばれ、ペアで存在している。鍵ペアは数学的な関係で成り立っていて、公開鍵から秘密鍵を導き出すことはできない。

DHEを例に、AさんとBさんがどのように共通鍵を共有するか解説。

  1. AさんはBさんにDHパラメータ(大きな素数pと生成元g)を送信し、共有する。pとgは数学的な関係で成り立っている。DHパラメータは秘密にする必要はなく、盗聴されても問題ない。
  2. Aさんは秘密鍵aを生成する。この秘密鍵aは「1~p-2」の範囲にある整数。相手に伝える必要はなく、Aさんの中で秘密にしておく必要がある。
  3. Bさんは秘密鍵bを生成する。この秘密鍵bは同じく「1~p-2」の範囲にある整数。相手に伝える必要はなく、Bさんの中で秘密にしておく必要がある。
  4. Aさんは秘密鍵aとDHパラメータを使用して公開鍵xを生成しBさんに送信する。具体的に言うと、Aさんはga mod pの計算式で公開鍵xを生成し、Bさんに送信する。この公開鍵xは秘密にする必要はなく、盗聴されても問題ない。また公開鍵xから秘密鍵aを導き出すことはできない。
  5. Bさんは秘密鍵bとDHパラメータを使用して公開鍵yを生成しBさんに送信する。具体的に言うと、Aさんはgb mod pの計算式で公開鍵yを生成し、Aさんに送信する。同じくこの公開鍵yは秘密にする必要はなく、盗聴されても問題ない。また公開鍵yから秘密鍵bを導き出すことはできない。
  6. Aさんは、受け取った公開鍵y、自分の秘密鍵a、DHパラメータを使用して共通鍵を計算する。具体的には公開鍵y( = gb mod p)をa乗して、mod pを取る。この式を簡単にすると gab mod pになる。
  7. Bさんは、受け取った公開鍵x、自分の秘密鍵b、DHパラメータを使用して共通鍵を計算する。具体的には公開鍵y( = ga mod p)をb乗して、mod pを取る。この式を簡単にすると gab mod pになる。つまり6.で計算した値と同じ。これでお互い共通鍵を導き出すことができた。

図:DHEによる共通鍵の共有

DHEはこのようなやり取りをSSLセッションごとに行い、SSLセッションごとに共通鍵を共有することでセキュリティレベルの向上を図っている。

DHEやECDHEなどの鍵交換アルゴリズムは、あくまで共通鍵を共有するためのものであって、通信相手をにんしょうしたり、改ざんを検知したりするものではない。通信相手が悪意のある第三者になりすましされていたり、途中で改ざんされていたりしたらその時点でアウト。通信相手が本物か。この認証問題を別の仕組みでクリアする必要がある。

デジタル署名アルゴリズム

デジタル署名はRSA署名というデジタル署名アルゴリズムによって生成されている。RSA署名はハッシュ化公開鍵暗号方式を組み合わせた技術。

ハッシュ化

ハッシュアルゴリズムを利用して、不定長のデータを細切れにして、固定長のハッシュ値にギュッとまとめる技術。代表的なアルゴリズムは「SHA-256」や「SHA-384」など。ハッシュアルゴリズムは同じデータを与えると、必ず同じハッシュ値を生成する。逆に1ビットでも違うデータを与えると、全く異なるハッシュ値を生成する。つまりデータそのものを比較しなくても、ハッシュ値を比較さえすればデータが改ざんされていないかをチェックできる。また、ハッシュ値から元のデータを逆算することはできないため、たとえハッシュ値を盗聴されたとしても、元のデータは守られる。

図:ハッシュ化

公開鍵暗号方式

暗号化鍵と複合鍵に異なる鍵を使用する暗号方式。代表的な方式に「RSA暗号」や「ElGamal暗号」などがある。ここではRSA署名に関連するRSA暗号について説明する。データの受信者は、あらかじめみんなに秘密にしておかないといけないRSA秘密鍵と、みんなに公開していいRSA公開鍵の鍵ペアを作り、RSA公開鍵だけを世の中に公開しておく。送信者はそのRSA公開鍵を暗号化鍵にして、データを暗号化し、送信する。それを受け取った受信者はRSA秘密鍵を複合鍵にして複合し、元データを取り出す。RSA公開鍵で暗号化されたデータは、ペアとなるRSA秘密鍵でしか複合できない。

RSA暗号に使用されるRSAアルゴリズムは、秘密鍵と公開鍵を逆にしても成立するという数学的に特異な性質を持っている。RSA署名はこの性質を利用。送信者はRSA秘密鍵を署名鍵にして、データの署名を生成し送信する。「署名を生成」とは実際には暗号化と同様の処理を行っている。それを受け取った受信者はRSA公開鍵を検証鍵として、署名を検証する。署名鍵で署名されたデータはペアとなる検証鍵でしか検証できない。

図:署名の生成と検証

デジタル署名の手順は以下。

  1. 送信者はハッシュアルゴリズムを利用してデータのハッシュ地を計算する。
  2. 送信者は1.で計算したハッシュ値やRSA秘密鍵(署名鍵)を使用して、デジタル署名を生成し、データとともに送信する。
  3. 受信者はデジタル署名をRSA公開鍵(検証鍵)で検証して、ハッシュ値を取り出す。RSA公開鍵で検証できたら、そのデータがRSA秘密鍵の持ち主によって送信されたものであることがわかる。
  4. 受信者はハッシュアルゴリズムを利用してデータのハッシュ値を計算し、3.で取り出したハッシュ値と比較する。ハッシュ値が同じだったら、データが途中で改ざんされていないことがわかる。

図:RSA署名

メッセージ認証アルゴリズム

デジタル署名はあくまで通信相手を認証するもので、その後やりとりされるアプリケーションデータを認証するものではない。そこでメッセージ認証アルゴリズムを利用して、MAC値(メッセージ認証コード)を生成し、データが改ざんされていないことを確認する。アプリケーションデータと共通鍵(MAC鍵)をごちゃ混ぜにして、ハッシュ化することによってMAC値を計算する。

図:ハッシュアルゴリズムとメッセージ認証アルゴリズムの違い

送信者はデータと共通鍵を使用してMAC値を計算し、データとともに送信する。

受信者は受け取ったデータと共通鍵を使用してMAC値を計算し、受け取ったMAC値と比較する。同じだったらそのデータが途中で改ざんされていないことになる。つまりメッセージ認証完了。

図:メッセージ認証アルゴリズム

ここまで説明してきたメッセージ認証アルゴリズムは、そのためだけに共通鍵(MAC値)を作って共有しないといけなかったり、メッセージごとにMAC値を計算しないといけなかったり、いろいろ非効率な部分がある感は否めない。そこで最近は、メッセージ認証の機能自体が共通鍵暗号方式の一機能として統合されている。メッセージ認証の機能を持つ暗号方式のことをAEAD(Authenticated Encryption with Associated Data, 認証付き暗号)という。ストリーム暗号のChaCha20-Poly1305やブロック暗号の中でもAES-GCMやAES-CCMはAEADにあたり、暗号化とメッセージ認証をまとめて行う。

送信者は、平文データやナンス(一意な乱数)、関連データ(暗号化は必要ないけど改ざんされてはいけないデータ。ヘッダーなど)を共通鍵で認証付き暗号化し、暗号化データとメッセージ認証に使用する認証タグを生成する。そして、暗号化データ、認証タグ、ナンス、関連データをまとめて送信する。受信者は受け取った暗号化データ、ナンス、関連データ、そして共通鍵で認証タグを生成し、受け取った認証タグと比較する。メッセージ認証に成功したら、共通鍵で平文データに複合する。

図:AEAD

SSLのレコードフォーマット

SSLによって運ばれるメッセージのことをSSLレコードという。SSLレコードは、SSLの制御情報を格納するSSLヘッダーと、そのあとに続くSSLペイロードで構成される。また、SSLヘッダーはコンテンツタイププロトコルバージョンSSLペイロード長という3つのフィールドで構成されている。

図:SSLレコードフォーマット

コンテンツタイプ

SSLレコードの種類を表す1バイトのフィールド。SSLはレコードをハンドシェイクレコード暗号仕様変更レコードアラートレコードアプリケーションデータレコードの4つに分類し、タイプコードを割り当てている。

表:コンテンツタイプ

ハンドシェイクレコード

アプリケーションデータの暗号化通信に先立って行われる「SSLハンドシェイク」で使用される。さらに10種類のハンドシェイクタイプが定義されている。

表:ハンドシェイクタイプ

暗号仕様変更レコード

SSLハンドシェイクによって決まったいろいろな仕様(暗号化アルゴリズムや鍵交換アルゴリズムなど)を確定したり、変更したりするために使用する。このレコード以降はすべて暗号化される。

アラートレコード

通信相手に対して、SSLに関係するエラーがあったことを伝えるレコード。アラートの深刻度を表す「Alert Level」と、その内容を表す「Alert Description」の2つのフィールドで構成されている。Alert Levelには「Fatal(致命的)」と「Warning(警告)」の2種類があり、Fatalだと直ちにコネクションが切断される。Alert Descriptionの中にはAlert Levelが定義されていないものもあり、定義されていないものに関しては送信者の裁量でAlert Levelを決めることができる。

表:Alert Description

アプリケーションデータレコード

その名のとおり、実際のアプリケーションデータ(メッセージ)が含まれるレコード。SSLハンドシェイクによって確定した共通鍵を使用して暗号化される。

プロトコルバージョン

SSLレコードのバージョンを表す2バイトのフィールド。上位1バイトがメジャーバージョン、下位1バイトがマイナーバージョンを表している。ちなみにバージョンフィールドにおいて、TLSはSSL3.0のマイナーバージョンアップ的な扱いになっている。

表:プロトコルバージョン

SSLペイロード長

SSLペイロードの長さをバイト単位で定義する2バイトのフィールド。214バイト(16384)以下になるよう定義されている。アプリケーション層から受け取ったデータが16384バイトを超える場合は16384バイトに分割されて暗号化される。

SSLの接続から切断までの流れ

事前準備フェーズ

  1. サーバー管理者はWebサーバーでRSA秘密鍵と、それに対応するRSA公開鍵を含む「CSR(Certificate Signing Request)」というファイルを作成する。RSA秘密鍵は「—–BEGIN RSA PRIVATE KEY—–」で始まり、「—–END RSA PRIVATE KEY—–」で終わるテキストファイル。RSA秘密鍵は機密情報なので大切に保管する。

図:RSA秘密鍵

CSRは、認証局にデジタル署名をお願いするための申請書のようなもの。CSRを作成するときには、ディスティングイッシュネームと呼ばれるWebサーバーの管理情報も併せて入力する。

表:ディスティングイッシュネーム

CSRは「—–BEGIN CERTIFICATE REQUEST—–」で始まり、「—–END CERTIFICATE REQUEST—–」で終わるテキストファイル。CSRができたら、そのテキストをコピーして、認証局の申請フォームの指定された部分にペーストして申請する。

図:CSR(Certificate Signing Request)

2. 認証局が申請元の身元を審査する。確認する内容は認証局や証明書の種類にもよるが、具体的にはドメインの管理者にメールしてドメイン名の使用状況を確認したり、直接管理者に電話して実在性を確認したりする。いくつかの確認ステップを経ると、晴れてデジタル署名が付与されたデジタル証明書がサーバー証明書として発行される。

サーバー証明書は「—–BEGIN CERTIFICATE—–」で始まり「—–END CERTIFICATE—–」で終わるテキストファイル。

図:サーバー証明書

3. 1で作成したRSA秘密鍵と、2で発行されたサーバー証明書をWebサーバーにインストールする。また、併せて中間証明書(中間CA証明書、チェーン証明書)という、サーバー証明書を発行した認証局の証明書をインストールする。

認証局はたくさんのデジタル証明書を管理するためにルート認証局中間認証局という2種類の認証局で構成された階層構造になっている。

ルート認証局は、階層構造の最上位に位置する認証局で、ルート証明書(ルートCA証明書)を発行している。ルート証明書はOSやWebブラウザにバンドルされていて、たとえばWindows11の場合、証明書マネージャーツール(certmgr.msc)の「信頼されたルート証明機関」 – 「証明書」をクリックすると確認できる。ルート証明書は、ルート認証局の秘密鍵でデジタル署名されている。つまり自分で自分を認証している。

図:Windows11にバンドルされているルート証明書

中間認証局は、ルート認証局の下位に位置する認証局で、サーバーにインストールするサーバー証明書を発行する認証局。つまりこれまで説明してきた認証局はこの中間認証局を意味している。中間認証局は上位のルート認証局から認証を受ける必要がある。中間認証局が上位認証局の秘密鍵でデジタル署名を受け、発行してもらったデジタル証明書が中間証明書。

Webサーバーにサーバー証明書と中間証明書をインストールすることによって、ルート証明書とサーバー証明書の信頼の連鎖をつなぐことができ、Webブラウザはそれをもとに証明書の階層を正しく辿ることができる。

図:認証局とデジタル証明書の階層構造

図:X(旧Twitter)のサーバー証明書階層

SSLハンドシェイクフェーズ(サーバー認証フェーズ、鍵交換フェーズ)

RSA秘密鍵とデジタル証明書のインストールが終わったら、いよいよWebブラウザからSSL接続を受け付けることができる。SSLはいきなりアプリケーションデータを暗号化して送りつけてくるわけではない。サーバーを認証したり、鍵交換したりするSSLハンドシェイクという処理がある。

SSLはTCPコネクションをオープンしたあと、ハンドシェイクコードを利用してSSLハンドシェイクを行い、そこで決めた情報をもとにメッセージを暗号化する。

ここからは暗号化アルゴリズムに「AES-GCM」鍵交換アルゴリズムに「DHE」デジタル署名アルゴリズムに「RSA署名」メッセージ認証は「AEAD(AES-GCM)」が使用される場合を例に説明する。

  1. Webブラウザは3ウェイハンドシェイクでTCPコネクションを確立した後、自分が対応している機能やそれに関する仕様をClient Helloに格納して送信する。

一言で認証する、暗号化する、といっても色々な種類のアルゴリズムがある。そこでWebブラウザは自分が対応している暗号化アルゴリズム、鍵交換アルゴリズム、デジタル署名アルゴリズム、メッセージ認証アルゴリズムの組み合わせ(暗号スイート)をリストとして提示する。またほかにもclient randomと呼ばれるランダムな文字列や、対応しているSSLやHTTPのバージョンなど、Webサーバーと合わせておかないといけない設定や拡張機能を伝える。

図:Client Hello

タイプコード拡張機能意味
0server_nameサーバーのドメイン名(FQDN)を格納する。1つのIPアドレスで、複数のHTTPSサーバーを運用するときに、この値を見て処理すべきHTTPSサーバーを識別する。
16application_layer_protocol_negotiation対応しているアプリケーション層プロトコルの一覧を格納する。HTTP/2接続のSSLハンドシェイクパターンで使用する。
23extended_master_secret拡張マスターシークレットに対応していることを示す。
43cupported_versionsTLS1.3において、対応しているTLSバージョンの一覧を格納する。

表:代表的な拡張機能フィールド

2. WebサーバーはClient Helloに含まれる情報と自信の設定を突き合わせ、確定した情報をServer Helloに格納して送信する。

Webブラウザがどんなにいろいろな暗号スイートに対応していたとしても、使用できるのは1つだけ。マッチした暗号スイートの中で最も優先度が高い(リストの最上位にある)暗号スイートを選択する。選択結果をserver randomと呼ばれるランダムな文字列や、そのほかのWebブラウザと合わせておかないといけない拡張機能とともに伝えて、以降に使用する機能や仕様を確定させる。

図:Server Hello

3. Webサーバーはインストールされているサーバー証明書と中間証明書をCertificateに格納して送信する。

Webブラウザは、サーバー証明書のデジタル署名を中間証明書に含まれるRSA公開鍵で、中間証明書のデジタル署名をルート証明書に含まれるRSA公開鍵で検証することによって、デジタル証明書の階層構造を辿り、「サーバー証明書と中間証明書が途中で改ざんされていないこと」や、「Webサーバーが認証局によって親裁されたサーバーであること」を確認する。また、アクセス先のドメイン名がサーバー証明書に含まれるドメイン名と一致していることを確認する。

図:Certificate

4. WebサーバーはDHEで使用する素数や生成元、DH公開鍵、そしてWebサーバーのRSA秘密鍵によって署名されたDH公開鍵のデジタル署名Server Eky Exchangeに格納して送信する

5. WebサーバーはServer Hello Doneで自分の情報を送り終わったことを伝える。

6. Server Key Exchangeを受け取ったWebブラウザは、Certificateに含まれていたRSA公開鍵でデジタル署名を検証し、「DH公開鍵が改ざんされていないこと」や「ペアとなるRSA秘密鍵を持っている相手であること」を確認する。またServer Key Exchangeに含まれていた素数、生成元、WebサーバーのDH公開鍵、自分のDH公開鍵からプリマスターシークレットという名前の共通鍵を作る。

図:Server Key Exchange ~ Server Hello Done

7. Webブラウザは自分のDH公開鍵をClient Key Exchangeに格納して送信する。

8. Client Key Exchangeを受け取ったWebサーバーは、素数、生成元、WebブラウザのDH公開鍵、自分の秘密鍵から同じくプリマスターシークレットを作る。これで同じプリマスターシークレットを共有することができた。ただ、SSLはこのプリマスターシークレットをそのまま使用するわけではない。

まず、これまでやりとりしたSSLハンドシェイクメッセージのハッシュ値(セッションハッシュ)とあわせてPRF(Pseudo Random Function, 疑似乱数関数)というハッシュアルゴリズムをベースにした特殊な計算を施すことによってマスターシークレットを作成する。そしてそこからさらにClient Helloに含まれているclient randomはServer Helloに含まれているserver randomとあわせて、PRFで計算し、アプリケーションデータの暗号化・複合に使用する複数の共通鍵(セッションキー)を作る。

9. 最後にお互いにChange Cipher SpecFinishedを交換し合ってSSLハンドシェイクを終了する。

Change Cipher SpecはここまでのSSLハンドシェイクで決めた内容を確定するメッセージ。「よし!じゃあ、これでいきましょう!」的な感じ。この次のメッセージから、つまりFinishedから暗号化通信が始まる。

FinishedはSSLハンドシェイクの終わりを表すメッセージ。これまでやりとりしたメッセージをハッシュ化し、verified_dataに格納する。このやり取りが終了するとSSLセッションができあがり、アプリケーションデータの暗号化通信のための下地づくりができる。

図:Client Key Exchange~Finished

メッセージ認証・交換フェーズ

SSLハンドシェイクが終わったら、いよいよアプリケーションデータの暗号化通信の始まり。AED-GCMはAEADなので、そのときメッセージ認証も併せて行う。

  1.  Webブラウザは、平文データやナンス、関連データをSSLハンドシェイクで作った共通鍵で認証付き暗号化し、暗号化データとメッセージ認証に使用する認証タグを生成する。そして暗号化データ、認証タグ、ナンス、関連データをまとめて送信する。


Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です