こんにちは!クラウドインテグレーション部技術2課の加藤ゆです!
さて今回は、TLS/SSLで使われる鍵の交換の話が1年前から分からず、逃げ続けてきたのでこの機会に本気を出してまとめました。
分からなかった事
- SSL通信で使われる鍵(秘密鍵・共通鍵・公開鍵)の関係
- AWS Certificate ManagerとSSL通信の関係
HTTPSでの通信をさせたい!という要件はよくあると思います。
アクセスする際にどんなやり取りがあるのか、サーバ側にはどんな設定が必要なのかを理解しないといけなかったので、クライアントとサーバそれぞれの目線でHTTPS通信の概要をまとめてみました。
証明書を使ったSSL暗号化通信(クライアント目線)
クライアントがサーバへ通信をするとき起こる事
DNSサーバに名前解決
1:このドメインのIPアドレスは? [クライアント]
2:XX.XX.XX.XX(IPアドレス)だよ [サーバ]
TCPの3wayhandshake
1:接続していい? [クライアント]
2:OK 接続していい? [サーバ]
3:OK [クライアント]
ものすごいザックリですが、こんな感じのやり取りが一番はじめに起こります。
SSL暗号化通信
大まかに4段階に分けました。
- クライアント-サーバ間での暗号化の仕様を決める
- サーバがクライアントに公開鍵 + SSLサーバ証明書を送る
- 乱数を利用して共通鍵を生成
- 暗号化通信開始
1. クライアント-サーバ間での暗号化の仕様を決める
①「暗号化の仕様が確定」
クライアントがWebサイトへアクセスし、SSL暗号化通信での接続を要求。
この要求時にクライアントが利用できる暗号化の仕様をサーバにお知らせします。
サーバは、クライアントが利用可能な暗号化仕様の内、実際に通信で利用するものをクライアントへお知らせします。
ここで通信で使う暗号化の仕様が決定。
2. サーバがクライアントに公開鍵 + SSLサーバ証明書を送る
②「サーバの正当性を検証」「サーバから公開鍵を貰う」
サーバは、自身を証明するSSLサーバ証明書(公開鍵入り)を、クライアントへ送信。
あらかじめクライアントに登録されている「信頼できる認証局」と、貰ったサーバ証明書に記載の認証局が一致するか、検証。
ここで証明書の正当性が認められなくても、通信の暗号化は可能です。ただし、サーバの正当性は担保されていない暗号化通信になります。
3. 乱数を利用して共通鍵を生成
③「共通鍵を生成」
ここで最終的に暗号化通信で利用される共通鍵を生成します。
- クライアントは、②で受け取ったサーバ証明書に含まれている、公開鍵を使用して、共通鍵を暗号化。暗号化した共通鍵をサーバに送信。
(※ 正確には、クライアントが共通鍵の基となる乱数情報(プリマスターシークレット)を生成し、公開鍵で暗号化して送信) - サーバは公開鍵のペアである秘密鍵を使用して、暗号化された共通鍵の復号化を行う。
※ 共通鍵の基となる乱数情報(プリマスターシークレット)を生成
「Client Key Exchange」
- 共通鍵を生成するために、正確にはプレマスターシークレットと呼ばれる乱数を生成しています。
- クライアントは、サーバの公開鍵で暗号化した乱数(プリマスタシークレット)を、サーバに送信。
- この値を基にクライアント・サーバがそれぞれマスターシークレットを生成し、マスターシークレットから、クライアント・Webサーバそれぞれで共通鍵を生成しています。
正確な表現を追記すると、以下の記載となります。
- クライアントは、共通鍵 [ の生成元となるプリマスターシークレットキー ] を公開鍵で暗号化して、サーバに送付
- サーバは、公開鍵のペアである秘密鍵で共通鍵 [ の生成元となるプリマスターシークレットキー ] を復号化
- [ サーバ・クライアント各々で、プリマスターシークレットキーからマスターシークレットキーを生成し、共通鍵を生成 ]
※[ ]内が追記された部分
4. 暗号化通信開始
④「SSL暗号化通信開始」
3で作成した共通鍵を利用し、以降はセッションが切れるまで共通鍵で暗号化・復号化して通信を行う。
SSL証明書を利用する通信のポイント
データの暗号化に利用する鍵(共通鍵)を、クライアント側で暗号化している部分が分からないポイントでした。共通鍵の受け渡し部分が着眼点だと思います。
- クライアント
- 公開鍵(サーバの秘密鍵から作られた)で共通鍵を暗号化する
- サーバ
- サーバしか持っていない秘密鍵を利用してクライアントから受け取った共通鍵を復号化する
証明書を使ったSSL暗号化通信(サーバー目線)
今まではクライアントがアクセスした際に、どんな鍵のやり取りがあるかの説明でした。
では、サーバ側ではどんな準備が必要なのでしょうか。
上記②でSSLサーバ証明書をクライアントに送っていましたよね。
ということは、このSSLサーバ証明書を作成し、クライアントがアクセスするサーバにインポートする必要があります。
HTTPS通信のためにサーバ側でやる事
1.認証局からWebサーバ用の証明書を生成してもらう
2.Webサーバに、生成した証明書をインポートする
これによりhttpsでの通信が可能になります。ではどうやって証明書を作ればよいのでしょうか。
SSLサーバ証明書は、認証局がWebサイト運営元を確認し、認証することで発行が出来るものです。今回詳しい説明は省きますが、3つの認証方式(DV(ドメイン)認証、OV(企業)認証、EV認証)から選択し、証明書を発行します。
AWS Certificate Manager (ACM)
AWSの場合、ドメイン認証による新規証明書の発行と、証明書の管理ができるサービスがあります。
AWS Certificate Manager (ACM) とは
AWS ウェブサイトとアプリケーションを保護するパブリックおよびプライベートの SSL/TLS X.509 証明書およびキーの作成、保存、更新に伴う複雑さに対処します。
参照: とはAWSCertificate Manager? - AWSCertificate Manager
AWSが提供するSSL/TLS証明書を発行・管理するマネージドサービスです。インターネット向けサイトを構築する際に利用することが出来るパブリック証明書の発行が出来ます。
今までの説明で、SSL/TSL通信にはサーバ証明書が必要だよ!という話をしていましたが、ACMはそこで利用するサーバ証明書を発行して管理してくれるサービスです。
ACMの使い方
証明書は、統合 AWS サービスACMで直接発行するか、インポート中サードパーティの証明書を ACM 管理システムに挿入します。ACM 証明書は、単一のドメイン名、複数の特定のドメイン名、ワイルドカードドメイン、またはこれらの組み合わせを保護できます。
新規発行
ACMでは、ドメイン認証で証明書の新規発行が可能です。
証明書の発行と管理 - AWSCertificate Manager
ドメインを所有しているのであれば、DNSへのレコード登録が可能であるため、証明書作成時に証明書リクエストのドメイン名の所有者または管理者を検証します。(DNS検証)
※ACMの場合Emailによる検証(Eメール検証)も選択可能
ドメインの所有者によってレコード登録が完了すると、証明書作成時の所有者の検証が完了し、作成が完了するといった流れとなります。
新規作成ではなく、サードパーティ製の証明書をアップロードして利用することももちろん可能です。
詳細については、こちら↑を御覧くださいませ。
まとめと感想
クライアント目線とサーバ目線でHTTPS通信を書いてみました。
HTTPS通信をさせるために、サーバには何が必要で、自分がサーバにアクセスするときには何が起きているのか?という部分が、両方の視点から理解できるといいなと思います。
また、サードパーティ製の証明書をACMにアップロードする時に、証明書の種類の判別ができずナンダコレと思った経験がありました。この記事で書こうかなと思ったのですが、まとまらない+書く根気が足りないので書くのをやめました… 証明書の種類は、どこかでもう一度詰まる(気がする)のでその時書きます。(たぶん)
参考資料
とはAWSCertificate Manager? - AWSCertificate Manager
【図解】よく分かるデジタル証明書(SSL証明書)の仕組み 〜https通信フロー,発行手順,CSR,自己署名(オレオレ)証明書,ルート証明書,中間証明書の必要性や扱いについて〜 | SEの道標