カスタマーサクセス部の山﨑です。
HTTPSやSMTPS等、広く利用されているSSL/TLSにおいて利用されている技術とその仕組みを整理してみました。
- SSL/TLSについて
- SSL/TLSで使用している3つの技術
- デジタル署名について深堀り
- SSL/TLSハンドシェイク
- まとめ
SSL/TLSについて
概要
SSL(Secure Sockets Layer)とTLS(Transport Layer Security)は、いずれもアプリケーションデータを暗号化して送受信する仕組み(プロトコル)です。個人情報やクレジットカード情報などの重要なデータを暗号化して、クライアント-サーバー間での通信を安全に行なうことができます。SSL/TLSには様々なバージョンがありますが、2024年現在はTLS1.2以上の利用が推奨されています。
SSL/TLSは以下3つの技術を組み合わせることでセキュリティ上の脅威に対抗しています。
技術 | 概要 |
---|---|
暗号化 | 共通鍵を使ってアプリケーションデータを暗号化することで、第三者からの盗聴を防ぐ。 |
ハッシュ化 | 一方向ハッシュ関数を用いてクライアント側で算出したハッシュ値と、サーバー側で算出したハッシュ値を照合して改ざんを検知する。 |
デジタル署名 | サーバー証明書/クライアント証明書を検証することで、対向ホストの身元を確認して、なりすましを防ぐ。 |
SSL/TLSで使用している3つの技術
暗号化
暗号化とは決められたルールに基づいて、元のデータを他の人に知られないように変換する技術です。
暗号化の代表的な例として「シーザー暗号」と呼ばれるルールがあり、平文に使われるアルファベットを辞書順に3文字分ずらして暗号文を作ります。この時、「平文に使われるアルファベットを辞書順にずらす」という変換方法をアルゴリズム、「3 文字」という変換ルールを鍵(キー)といいます。暗号化においてアルゴリズムの仕様は公開されているため、鍵(キー)の取り扱いが極めて重要となります。
電子データにおける暗号化では一般的に以下に示す3つの暗号化方式が利用されており、SSL/TLSにおいてはハイブリッド暗号化方式を採用しています。
暗号化方式 | 概要 | 特徴 |
---|---|---|
共通鍵暗号化方式 | クライアントとサーバーが同じキーを使って、データの暗号化/復号化を行う。 | ・処理負荷が低い ・処理速度が速い ・通信相手ごとにキーを作成管理する必要がある ・キーが漏洩したら盗聴が可能になるので配送方法に注意が必要(鍵配送問題) |
公開鍵暗号化方式 | クライアントとサーバーが異なるキー(秘密鍵/公開鍵)を使って、データの暗号化/復号化を行う。 | ・処理負荷が高い ・処理速度が遅い ・秘密鍵で暗号化したデータは公開鍵で、公開鍵で暗号化したデータは秘密鍵でのみ復号できる ・秘密鍵で暗号化=デジタル署名、公開鍵で暗号化=データ暗号化の用途が一般的 |
ハイブリッド暗号化方式 | セッション開始前にまず公開鍵暗号化方式を用いて共通鍵生成の素となる値を共有し、その値を使ってクライアントとサーバーでそれぞれ生成した共通鍵を用いて暗号化/復号化を行う | ・共通鍵暗号化方式の鍵配送問題を解消することができる ・処理負荷が高い ・処理速度が遅い |
ハッシュ化
ハッシュ化とは一方向ハッシュ関数という特殊な計算方法を用いてデータを一定のサイズにまとめる技術で、まとめられたデータはハッシュ値 / メッセージダイジェスト / フィンガープリントと呼ばれます。
例えば、「サーバーワークスエンジニアブログ」という文字列データを「SHA-256」でハッシュ化すると、256bitのハッシュ値が算出されます。
- 計算元データ:サーバーワークスエンジニアブログ
- ハッシュ値:398f559b2e3e3054b5854447661811d7373a0706a32c1b9a50632156c09bf9d1
以下、ハッシュ化の特徴です
No | 特徴 | 概要 |
---|---|---|
1 | ハッシュ値のサイズは固定 | 大小様々なデータも固定長データとなるため扱いやすい |
2 | 計算元データが同じであれば、ハッシュ値は同じ | 計算元データが同じであれば、何度計算してもハッシュ値は同じになる |
3 | 計算元データが異なれば、ハッシュ値は異なる | 計算元データが異なれば、ハッシュ値は異なる |
4 | ハッシュ値から元データを算出することはできない | ハッシュ値はあくまでデータの要約であるため、第三者に盗まれたとしても復元することはできない |
ハッシュ化にはNo.3の特徴があるため、計算元データが改ざんされた場合に検出することが可能となります。
デジタル署名
デジタル署名とは公開鍵暗号化方式を利用して、通信相手の認証 / 送信者の否認防止 / データの改ざん検知を行うために利用される技術です。
デジタル署名は以下の手順で行われます。
No | 処理 | 備考 |
---|---|---|
1 | データ送信者が秘密鍵と公開鍵を作成し、公開鍵を一般に公開する | ー |
2 | データ送信者は送信データを一方向ハッシュ関数でハッシュ値にし、ハッシュ値を秘密鍵で署名する | 暗号化されたハッシュ値をデジタル署名と呼ぶ |
3 | データ送信者は送信データとデジタル署名を合わせて相手に送信 | ー |
4 | データ受信者は公開鍵でデジタル署名を復号化する | 復号化できる=データは対となる秘密鍵で暗号化されているということが分かる。 よって、通信相手はキーペア作成者であることが分かる(通信相手の認証、送信者の否認防止) |
5 | データ受信者は受信データを一方向ハッシュ関数でハッシュ値にし、No.4で復号化したハッシュ値と照合する | データの改ざん検知を行っている |
デジタル署名について深堀り
デジタル署名とデジタル証明書
デジタル署名はデジタル証明書と呼ばれるサーバーの身元検証を行う際に利用するデータに利用されています。デジタル証明書は以下3つの要素から構成されています。
構成要素 | 内容 |
---|---|
署名前証明書 | サーバー(FQDN)やサーバの所有者等、証明書の有効期限や公開鍵等の情報が記載されている |
署名アルゴリズム | 署名時に利用する一方向ハッシュ関数が記載されている |
デジタル署名 | 署名前証明書を署名アルゴリズムでハッシュ化した値を、認証局の秘密鍵で暗号化(署名)したもの |
デジタル証明書の発行と利用準備
デジタル証明書は以下のプロセスで発行、利用準備を行います。
1. SSL/TLSサーバー(TLS終端装置)で秘密鍵を作成する
以下はopensslコマンドを用いてファイル名を「server.key」、アルゴリズムをRSA、鍵長を2048bitで作成しています。
$ openssl genrsa -out server.key 2048
2. 「CSR(Certificate Signing Request)」を作成し、認証局へ提出
サーバー証明書を認証局に作成してもらうためにCSR(Certificate Signing Request:証明書の署名要求)を作成します。
以下はopensslコマンドを用いてCSRを作成しています。コマンドを実行するとプロンプト上で「組織名」「住所」「SSL/TLSサーバのFQDN」などの入力が求められます。つまり、CSRの作成は署名前証明書の作成と同義です。作成されるCSRには、秘密鍵「server.key」を元に生成された対となる公開鍵の情報が含まれます。
$ openssl req -new -key server.key -out server.csr
3. 認証局による審査
DigiCertなどの認証局へCSRを提出して、審査を行ってもらいます。認証局によって差はありますが、基本的には発行する証明書のタイプによって審査基準が異なります。
証明書のタイプ | 検証レベル | 概要 |
---|---|---|
DV証明書 | 低 | ウェブサイトを運営する際に使っているドメイン名(例:example.com)が、申請者のものであることを証明するための証明書 認証局は、メールやDNSレコードを利用してドメインの所有権を確認するだけなので、発行が迅速で、手続きも容易 |
OV証明書 | 中 | ドメインの検証に加えて、ウェブサイトが属する組織が実在して運営されていることを確認 認証局は組織の法的文書、運営状態、物理的な所在地などを確認 |
EV証明書 | 高 | OV証明書の審査内容に加えて、組織の運営状態、法的・物理的・運営を確認 さらに、申請者の身元確認と権限確認等を行う。 |
4. 認証局から送付されるサーバー証明書をSSL/TLSサーバー(TLS終端装置)に配置する
認証局による審査が完了したら、認証局からサーバー証明書および中間証明書が送付されてきますので、サーバーの所定の場所へ設置します。
例えば、ApacheでSSL/TLSを有効化する際に設定する以下のディレクティブはサーバー証明書および中間証明書の設置場所を指定しています。
SSLCertificateFile "/path/to/your/certificate.crt" SSLCertificateChainFile "/path/to/your/chainfile.pem"
デジタル証明書を用いた通信相手の身元検証
デジタル証明書を受け取ったクライアントは以下のプロセスでサーバーの身元検証を行います。
- デジタル署名を認証局の公開鍵で復号化してハッシュ値を取得する
- 署名前証明書を署名アルゴリズムでハッシュ化し、ハッシュ値を算出する
- 復号化したハッシュ値と、自身で算出したハッシュ値が一致しているかどうかを照合する
SSL/TLSハンドシェイク
SSL/TLSを用いた暗号化通信は、3ウェイハンドシェイクでTCPコネクションを確立した後に、SSL/TLSハンドシェイクを行うことで利用可能になります。以下、TLS1.2におけるSSL/TLSハンドシェイクについて説明します。なお、今回はクライアント認証のステップは割愛してサーバー認証にスポットライトを当てますが、やっていることは似ています。
暗号スイートの合意
①Client Hello
- サポートしている暗号スイート(暗号化方式、ハッシュ化方式、データ圧縮方式 etc)をサーバー側へ送信
- セッションID、client random challenge(共通鍵生成で使用するランダム文字列)等も合わせて送信
- セッションIDは「SSLセッションリザンプション」でセッションを再利用する際に利用
②Server Hello
- クライアントがサポートしている暗号スイートとサーバーがサポートしている暗号スイートを照合してマッチしたものの中から優先度が高いものを1つ選び、セッションIDとともにクライアントへ送信
- サーバー側で利用可能な暗号化スイートがなければ接続は失敗
- server random challenge(共通鍵生成で使用するランダム文字列)等の情報を応答
ALBの設定項目のなかにセキュリティポリシーというものがありますが、これはALBがサポートしている暗号スイートを設定しています。
Application Load Balancer 用の HTTPS リスナーを作成する - Elastic Load Balancing
通信相手(サーバー)の身元検証
③Server Certificate
- サーバー証明書および中間証明書をまとめてクライアントへ送信
④Server Key Exchange
- 追加で必要な暗号化パラメータがあればデジタル署名と合わせてクライアントへ送信
- 例えば、DH鍵交換をServer Helloで応答した場合、そこで利用するパラメータ = g(基底) , p(大きな素数)を送信
⑤Server Hello Done
- サーバーからクライアントへ送信する情報を送り終わったことを通知
- クライアント側では「証明書チェーンの検証プロセス」によってサーバー証明書および中間証明書の検証が行われる
証明書チェーンの検証プロセス
Server Hello Done が完了すると、クライアント側で通信相手(サーバー)の身元検証が実施されます。
サーバーから送信されてきたサーバー証明書の署名前証明書にはサーバーやドメインに関する情報が記載されているため、通信相手(サーバー)が本当に通信したい相手なのかどうか、その身元を確認することができます。しかし、その証明書自体が信頼できるものなのかどうかはクライアントでは判断できません。
そこで信頼できる第三者機関のお墨付きを確認できれば、信頼できる証明書として受理しようという考え方が証明書チェーンです。この証明書チェーンの頂点、つまり最も信頼できるとされる第三者機関をルート認証局と呼びます。この証明書チェーンはルート認証局が信頼できることが前提となるため、ルート認証局は厳しい審査を経ることで、認証局として認められます。
証明書チェーンの検証プロセスは主に以下の4段階で行われます。
- 発行元(Issuer)の確認:サーバー証明書の「サブジェクト」のDN(Distinguish Name)がドメイン名と一致するかを確認します。
- 有効期限の確認:各証明書の有効期限が切れていないことを確認します。
- 署名の検証:各証明書が正しい認証局によって署名されているかを確認します。これにより、証明書が改ざんされていないことを保証します。
- 撤回のチェック:証明書が失効リスト(CRL)やオンライン証明書ステータスプロトコル(OCSP)によって失効されていないかを確認します。
以下、「署名の検証」について詳説します。
中間証明書の検証
- クライアントは、Webブラウザ等に予めインストールされているルート証明書に含まれている公開鍵を使って中間証明書のデジタル署名を復号化します。
- 中間証明書の署名前証明書を同じ署名アルゴリズムでハッシュ化し、そのハッシュ値と復号化した値が一致するかを確認します。一致すれば、中間証明書はルート認証局によって発行され、改ざんされていないことが証明されます。
サーバー証明書の検証
- クライアントは、中間証明書の公開鍵を使用してサーバー証明書のデジタル署名を復号化します。
- サーバー証明書の署名前証明書を同じ署名アルゴリズムでハッシュ化し、そのハッシュ値と復号化した値が一致するかを確認します。一致すれば、サーバー証明書が中間認証局によって発行され、改ざんされていないことが証明されます。
共通鍵の生成
⑥Client Key Exchange
- (RSA方式の場合)
- プリマスターシークレットと呼ばれるランダムなデータをサーバー証明書に含まれている公開鍵を用いて暗号化して、サーバーへ送信
- (公開鍵暗号化方式 - DH/ECDH の場合)※ 安全性は高い - 前方秘匿性
- DH/ECDHで必要な暗号化パラメータがあればデジタル署名と合わせてクライアントへ送信
- 例えば、DH鍵交換をServer Helloで応答した場合、そこで利用するパラメータ = g(基底) , p(大きな素数)を送信
- クライアントとサーバーがそれぞれ、 g(基底) , p(大きな素数) を用いて独立して計算することで同一の値(プリマスターシークレット)を生成
- DH/ECDHで必要な暗号化パラメータがあればデジタル署名と合わせてクライアントへ送信
⑦Change Cipher Spec
- 「client random」「server random」「プリマスターシークレット」とハッシュ関数を組み合わせて「マスターシークレット」を生成する
- 「マスターシークレット」をもとに以下の鍵を生成する
- 共通鍵(セッション鍵):データ送受信時にデータを暗号化/復号化する暗号鍵
- 初期化ベクトル (IV):ブロック暗号を使用する場合、暗号化の各ブロックが前のブロックに依存しないようにするために初期化ベクトルが用いられます。これにより、同じデータブロックが同じ出力を生成することを防ぐ。
- HMAC用の共通鍵:HMAC(Hash-based Message Authentication Code)は、メッセージの完全性と認証を保証するために使用されます。つまり、送信されたデータが途中で改ざんされていないことを検証するのに役立ちます。
- Client Hello / Server Hello で合意した暗号化スイートを用いて通信を開始する準備ができた(今後は暗号化が有効になる)ことを示すメッセージをサーバーへ送信する
SSL/TLS通信開始の最終確認
⑧Finished
- Client Hello / Server Hello で合意した暗号化スイートを用いて、このメッセージより前にハンドシェイクで送受信した全データをHMACと合わせて、暗号化メッセージとして送信
- ハンドシェイクの終わりを示すメッセージでもある
メッセージ認証コード(MAC - Message Authenticate Code)について
MACはデジタル署名と同様に通信相手の認証 / 送信者の否認防止 / データの改ざん検知を行うために利用される技術です。デジタル署名は公開鍵暗号化方式を用いて署名を作成するのに対して、MACでは共通鍵暗号化方式を用いて認証コードを作成します。
HMAC(Hash-based Message Authentication Code)はハッシュ関数を利用して算出した認証コードを示しています。
⑨Change Cipher Spec
- 「client random」「server random」「プリマスターシークレット」とハッシュ関数を組み合わせて「マスターシークレット」を生成する
- 「マスターシークレット」をもとに以下の鍵を生成する
- 共通鍵(セッション鍵):データ送受信時にデータを暗号化/復号化する暗号鍵
- 初期化ベクトル (IV):ブロック暗号を使用する場合、暗号化の各ブロックが前のブロックに依存しないようにするために初期化ベクトルが用いられます。これにより、同じデータブロックが同じ出力を生成することを防ぐ。
- HMAC用の共通鍵:HMAC(Hash-based Message Authentication Code)は、メッセージの完全性と認証を保証するために使用されます。つまり、送信されたデータが途中で改ざんされていないことを検証するのに役立ちます。
- Client Hello / Server Hello で合意した暗号化スイートを用いて通信を開始する準備ができた(今後は暗号化が有効になる)ことを示すメッセージをサーバーへ送信する
- サーバーは生成されたHMAC用の鍵(クライアントと同一のものが生成される)を用いてFinishメッセージを検証することで通信相手の身元確認と改ざん検知をしている
⑩Finished
- Client Hello / Server Hello で合意した暗号化スイートを用いて、このメッセージより前にハンドシェイクで送受信した全データをHMACと合わせて、暗号化メッセージとして送信
- ハンドシェイクの終わりを示すメッセージでもある
まとめ
ということで、今回はSSL/TLSにおいて利用されている技術とその仕組みを整理してみました。3ウェイハンドシェイクだけでなく、SSL/TLSハンドシェイクも実行するとなるとサーバーの負荷が高くなることも頷けます。これらの処理をオフロードしてサーバーの負荷を軽減させることができるロードバランサーという技術の素晴らしさも理解できました。