こんにちは、CSIG 所属の市川です。普段は FutureVuls という脆弱性管理サービスの開発・カスタマーサポートをしています。
「ん?そういえば、HTTPS 通信 (HTTP over SSL/TLS) では実際どのようにセキュアな通信が確立されているんだろう?」 と、ふと気になってしまうこと、ありませんか?私はありました。
というわけで、SSL/TLS について書籍などで学んでみたのですが…
- アルゴリズムが沢山出てきて頭がこんがらがる…。結局どのフェーズでどのアルゴリズムが使われているんだろう?
- TLS ハンドシェイクの中では、実際どういった通信が行われているのだろうか。ハンドシェイク確立後はちゃんと暗号化されているのだろうか。
…というモヤモヤが残りました。
本記事 (理論編) と、続編の実践編で、この2点の疑問を解決していきます。
本記事でやりたいこと
本記事 (理論編) では、以下の3点について解説します。
- 各アルゴリズムが何のために使われるかを整理する
- TLS1.2ハンドシェイクの各フェーズで使用されるアルゴリズムと送信される情報を、シーケンス図を用いて整理する
- 鍵交換方式 (どのようにして暗号化に用いる共通鍵を共有するか) について理解を深める
なお、実践編では以下を行っていきます。「細かいことはいいから、通信の中身を見たい」という方は、続編の実践編をお読みください。
- 「Wireshark」というツールを用いて TLS ハンドシェイクの中身を実際に覗いてみて、理論編の内容を確認する
TLS1.3 だと、ハンドシェイクの序盤で通信が暗号化されるのですが、今回の環境では通信の復号がうまく行えず、ハンドシェイクの中身を平文で確認することができませんでした。そのため、本記事は TLS1.2 をベースに解説しています。また、「実践編」でも TLS1.2 の通信を扱います。
TLS1.3ハンドシェイクはTLS1.2ハンドシェイクとは大きく異なります。TLS1.3 について理解したい方は、以下の書籍などを参考にしてください。
本記事では扱わない内容
上記の「本記事でやりたいこと」に解説するポイントを絞るため、以下については本記事での解説の対象外としています。あらかじめご了承ください。
- PKI (公開鍵基盤) まわりについての解説
- ハンドシェイク後の暗号化についての解説
理論編
どうして SSL/TLS 通信が必要なのか
セキュアな通信のためには、以下の4点に気を付ける必要があります。
- 「なりすまし」されても気づけるようにする
- 「否認」されないよう、本人でしか送付できない情報形式にする
- 「改ざん」されても検知できるようにする
- 「盗聴」されてもデータが読めないようにする
SSL/TLS を用いることで、これらを実現することができます。
SSL/TLS で用いられる手法と、使用される代表的なアルゴリズム
上記4点を保証するため、それぞれ以下のような手法とアルゴリズムが用いられます。
防ぎたいもの | 用いられる手法 | 使用される代表的なアルゴリズム |
---|---|---|
なりすまし、否認 | 電子署名を用いた認証 | RSA, ECDSA |
改ざん | MAC (メッセージ認証符号) を用いた改ざん検知 | SHA 256 (ハッシュ値生成に使用) |
- | 暗号化のための鍵の交換 | DHE, ECDHE |
盗聴 | データの暗号化 | AES |
TLS1.2 ハンドシェイクのシーケンス図
SSL/TLS通信は大きく、ハンドシェイクフェーズと、暗号化後のデータ転送フェーズに分けられます。
このうち、ハンドシェイクフェーズの流れとしては、大まか以下の通りです。
- 使用する暗号化スイートの合意
- 認証アルゴリズム
- 共通鍵暗号方式 (データ転送時に使う暗号化用アルゴリズム)
- ハッシュアルゴリズム
- サーバーの認証
- データ転送で使用する鍵の確立
- ハンドシェイク中の改ざん検知
TLSハンドシェイクが上記のステップで行われた場合に、サーバとクライアント間でやり取りされる各メッセージと値について、以下のシーケンス図にまとめました。
シーケンス図内では、各アルゴリズムを太字で表記しています。各フェーズでどのアルゴリズムがなんのために使われるかの整理に活用いただければ幸いです。
今回は、以下の暗号スイートが用いられていると仮定しています。
用途 | アルゴリズム |
---|---|
認証(電子署名) | RSA |
ハッシュ化 | SHA256 |
鍵交換 | ECDHE |
データの暗号化 | AES |
.png)
実践編では、これらの各フェーズにおける通信の中身を確かめていきます。
ステップ3 の鍵の確立方法についての補足
「鍵の確立方法」は、TLSハンドシェイクの流れを理解するために特に重要なので、補足します。データ転送フェーズでは、共通鍵を使用してデータの暗号化を行います。この共通鍵を作成するために「プリマスターシークレット」を生成する必要があります。
そして、このプリマスターシークレットは、「鍵交換アルゴリズム」を用いることで生成されます。
鍵交換の際に行われることについて、以下に超ざっくりまとめます。
シーケンス図および通信の中身について理解する上では、以下くらいの粒度で理解しておけば問題ないかと思います。
- サーバとクライアントの双方が秘密鍵を生成し、保持する
- 秘密鍵とパラメータ (ECDHE の場合は
named_curve
) から公開鍵を生成し、サーバ⇄クライアント間で交換する - 相手から受け取った公開鍵と自身が保持する秘密鍵から、プリマスタシークレットを生成する
- プリマスタシークレットは、サーバとクライアントで同じものになる
以下、代表的な鍵交換アルゴリズムである
- DHE (Diffie-Hellman Ephemeral)
- ECDHE (Elliptic curve Diffie–Hellman Ephmeral)
の2つについて、もう少し詳しく紹介します。
DHE (Diffie-Hellman Ephemeral)
DHE の仕組みはざっくり以下の画像のような感じです。
鍵交換方式として DHE を用いることで、秘密鍵

DHE ではセッションごとに新しい乱数とパラメータを使って鍵交換を行うため、前方秘匿性 (= あるセッションの鍵が漏洩しても、過去のセッションの通信内容を復号できない性質) が得られます。(DHEのE: Ephemeral
は、「パラメータが使い捨てであること」を指しています。)
ただし、DHE にはセキュリティレベルを担保しようとすると、処理が遅くなるという欠点があります。これは、DHE を用いて高いセキュリティレベルを担保しようとした場合、非常に大きい素数を用いる必要があり、計算量が大きくなってしまうためです。
ECDHE (Elliptic curve Diffie–Hellman Ephmeral)
DHE と同様に前方秘匿性のある鍵交換方式として、 ECDHE が挙げられます。
DHE では冪乗の計算が使用されますが、ECDHE では楕円体上の掛け算が使用されます。ECDHE を用いることで、DHEよりも少ないビット長で高いセキュリティレベルを確保できるため、こちらが現在の鍵交換方式の主流となっています。
RFC7748 において Curve25519
と Curve448
と呼ばれる楕円曲線が定義されており、計算に必要なパラメータ一覧が事前に定義されています。
そのため通信の際は、 named_curve
というパラメータにいずれかの曲線名を指定するだけで、計算に必要なパラメータをクライアント・サーバ間で共有することができます。
ECDHE鍵共有のアルゴリズム自体を深く知りたい場合は、円曲線暗号のPythonによる実装その1(有限体とECDH鍵共有), SEC 2: Recommended Elliptic Curve Domain Parameters なども参考になるかと思います。
まとめ
両者の特徴をまとめると、以下のようになります。
前方秘匿性 | 使用される数学 | セキュリティを担保するための計算量 | |
---|---|---|---|
DHE | あり | 素数体、冪乗 | 大 |
ECDHE | あり | 楕円体、掛け算 | 小 |
まとめ
理論編では、以下の3点について解説してきました。
- 各アルゴリズムが何のために使われるかを整理する
- TLS1.2ハンドシェイクのを、シーケンス図を用いて整理する
- 鍵交換方式について理解を深める
実践編では、「Wireshark」というツールを用いて TLS ハンドシェイクの中身を実際に覗いてみて、理論編の内容を確認していきます。
参考文献
⚪︎全体
SSL/TLS の仕組みを勉強する上で、以下の技術書が非常に参考になりました。
特に、1冊目は非常に体系的かつ網羅的にまとまっているので、SSL/TLS について勉強したい人は持っておいて損はないと思います。2冊目も分かりやすく、SSL/TLS について応用情報程度の知識しかなかった自分でも理解しやすかったです。自己証明書の作成なども、こちらの本を参考にしました。 (ただし、少し古めの本で、TLS1.3 については書かれていません。)
⚪︎ DHの理解
Diffie-Hellman 鍵交換方式については、以下を参考にしました。
- RFC 7748 - Elliptic Curves for Security 日本語訳
- TLS・SSLハンドシェイクの仕組みは? | Cloudflare
- 楕円曲線暗号のPythonによる実装その1(有限体とECDH鍵共有)
- RFC 7748 - Elliptic Curves for Security
- Standards for Efficient Cryptography | SEC 2: Recommended Elliptic Curve Domain Parameters
⚪︎ Wireshark
wireshake でハンドシェイクを確認する方法については、以下を参考にしました。