はじめに
TLSは初めて通信するクライアントとサーバが安全でないインフラ上で安全に通信するためのプロトコルです。 TLSの前身となったSSLと合わせて、SSL/TLSと呼ばれることもあります。 ここではTLSのバージョンが1.3であることを前提にお話します。TLS 1.3はそれ以前のバージョンとの互換性はない点に注意してください。
TLSが提供する安全な通信路は次の特性を持っています。
-
認証:クライアントは通信しているサーバが意図する接続先かどうかを常に確認します。 これにより攻撃者によるなりすましを防ぎます。 同様にクライアント側の認証も可能です。つまり、認証されたクライアントだけがサーバと通信できるようにすることもできます。 認証には公開鍵暗号(ECDSAやEdDSAなど)か事前共有鍵(PSK)が使われます。
-
機密性:通信確立後に送受信されるデータは全て暗号化されます。サーバが送信する証明書やプロトコル通信時や暗号復号時のエラーメッセージも全て暗号化されます。 これにより攻撃者による通信内容の解析・解読を防ぎます。 TLSは送信するデータ長は傍受されますが、TLSレコードを埋め込んでデータ長さをごまかすことも可能です。
-
完全性:通信確立後に送受信されるデータは、HMACやAEAD暗号による改ざん検知を行います。 これにより攻撃者による通信内容の改ざんや中間者攻撃を防ぎます。
TLSの通信は「暗号化通信を確立する」段階と「暗号化データを送受信する」段階の2つの段階があります。 それぞれでは暗号化に使う鍵が異なる点に注意してください。
- ハンドシェイクプロトコルと呼ばれる「暗号化通信を確立する」通信では、暗号化の方式とパラメータや共有鍵を作るために必要な乱数などをやりとりします。 ClientHelloとServerHelloの通信で得られた共通鍵からハンドシェイク暗号化用の鍵を導出し、以降のハンドシェイクの通信は全て暗号化されます。
- レコードプロトコルと呼ばれる「暗号化データを送受信する」通信では、上位レイヤの通信を暗号化したレコードに乗せて通信します。 各レコードは共通鍵からレコード暗号化用の鍵を導出し、その鍵で個別に暗号化されます。
TLS 1.3の特徴
暗号スイートの選別
TLS 1.2 は (319 + 37) 個の暗号スイートが使えますが、TLS 1.3 では 5 個のAEAD暗号を使う暗号スイートだけになり、より改ざんに対する安全性が高まりました。TLS 1.3 で使用可能な暗号スイートの一覧は次の通りです。
- TLS_AES_128_GCM_SHA256 : ハードウェアアクセラレーションを搭載したPCを含め、多くのコンピュータシステムで高速に動作
- TLS_AES_256_GCM_SHA384 : 上記の亜種。量子コンピュータへの考慮が必要な場合など安全性に猶予を持たせること想定
- TLS_CHACHA20_POLY1305_SHA256 : AES-GCM用のハードウェアアクセラレーションがないモバイル端末向けの高速な暗号スイート
- TLS_AES_128_CCM_SHA256 : IoT用の端末向けに最適化した暗号スイート。AES-GCMやChaCha20よりも高速。ICVが16オクテット
- TLS_AES_128_CCM_8_SHA256 : 上記のICVが8オクテット版
鍵交換アルゴリズム
TLS 1.3 では鍵を共有する方法として、DHEやECDHEの鍵交換アルゴリズムを使う方法と、事前共有鍵 (PSK) を使う方法と、その両方を使う方法を提供しています。
-
DHE : 有限体上のDiffie-Hellman鍵交換で鍵を共有します。以下の5つの群が使用できます。
- secp256r1
- secp384r1
- secp521r1
- x25519
- x448
-
ECDHE : 楕円曲線上のDiffie-Hellman鍵交換で鍵を共有します。以下の5つの群が使用できます。
- ffdhe2048
- ffdhe3072
- ffdhe4096
- ffdhe6144
- ffdhe8192
- PSK : 事前に両者で共有済みの鍵を使って暗号化します。そのため前方秘匿性はなくなります。
- PSK with (EC)DHE : 事前共有鍵PSKと(EC)DHE鍵交換アルゴリズムを使って共有した鍵で暗号化します。PSKは固定ですが、(EC)DHEでランダムな鍵になるので、前方秘匿性を維持することができます。
署名アルゴリズム
TLS 1.3 で使える電子署名アルゴリズムは以下の2種類です。
- RSA (PKCS#1 variants)
- ECDSA / EdDSA
ハンドシェイクの変更 (証明書の暗号化)
TLS 1.3 ではClientHelloとServerHello以降のメッセージが全て暗号化されるため、送信した証明書データも暗号化されます。 これにより、証明書の内容から誰が通信しているかという情報が秘匿されます。 特にクライアント証明書が暗号化されることで、クライアントの誰が通信しているかという情報が秘匿されます。
ハンドシェイクの変更 (1-RTT)
TLS 1.2 ではハンドシェイクが完了するまでに2往復の通信 (2-RTT) が必要でしたが、 TLS 1.3 では1往復の通信 (1-RTT) だけで完了します。 そのため、暗号化通信開始までの通信速度が向上します。
Early Data (0-RTT)
0-RTT は TLS 1.3 で導入された新しいプロトコルの機能です。 0-RTT は、セキュリティを犠牲にしてパフォーマンスを向上させる手法です。 直前の暗号化通信で得たエクスポートマスターシークレット (Export Master Secret) を使ってTLSセッションを開始する際は、ハンドシェイクをしない (0-RTT) で暗号化通信を開始することができます。 0-RTT で送信する暗号化データを早期データ (Early Data) と呼びます。 0-RTT は鍵を使い回しているため、0-RTT で暗号化したデータの前方秘匿性はなく、リプレイ攻撃に弱くなりますが、例えば 1-RTT のハンドシェイクでHTMLファイルを取得し、0-RTT で追加で必要なCSSファイルやJSファイルを取得する、といった感じで1回目と2回目の通信内容が連続していてリプレイされても困らないデータの送受信の場面で使うことで、暗号化通信の通信速度が向上します。
TLSの歴史
TLSの前身であるSSLは初めて世の中に公開されたのは1994年です。 Microsoft社とNetscape社による争いを経て、IETFに移管されて「TLS」という名前になりました。 SSL/TLSの公開年の歴史は以下のようになっています。
年 | 発行者 | バージョン | |
---|---|---|---|
1994 | Netscape | SSL 1.0 設計 | 組織内部でプロトコルの脆弱性が見つかったため設計段階で非公開 |
1994 | Netscape | SSL 2.0 公開 | 公開後すぐにセキュリティプロトコルとして重大な脆弱性が見つかる |
1995 | Netscape | SSL 3.0 公開 | 現在のTLSプロトコルの基本となる |
1999 | IETF | TLS 1.0 公開 | IETFに移管される。わずかな修正が入ったが、SSL 3.0との互換性はない。RFC 2246 |
2006 | IETF | TLS 1.1 公開 | セキュリティに関する修正。TLS拡張の追加。RFC 4346 |
2008 | IETF | TLS 1.2 公開 | AEAD(認証付き暗号)に対応。RFC 5246 |
2018 | IETF | TLS 1.3 公開 | AEAD以外の暗号を削除。前方秘匿性の提供。ハンドシェイクの改善。RFC 8446 |
現在の最新バージョンは TLS 1.3 です。ハンドシェイクが2往復から1往復になったことでパフォーマンスが改善し、AEAD以外の暗号スイートの削除や、鍵共有にDHEかECDHEだけを使うことで前方秘匿性を提供するようになり、速度面でも安全面でも改善がありました。
余談ですが、TLSのRFCの番号は末尾が必ず46で終わるようになっています。
用語
TLS暗号化通信の解説で使う用語の説明です。
- クライアント (client) : TLS接続を開始する側のエンドポイント
- サーバー (server) : TLS接続を開始しない側のエンドポイント
- エンドポイント (endpoint) : クライアントまたはサーバー
- ハンドシェイク (handshake) : TLSでクライアントとサーバ間の暗号化通信を確立するための最初のやりとり
- ネゴシエーション (negotiation) : パラメータなどを決定するためのやりとり
- ピア (peer) : 通信相手
- 〜シークレット (~ secret) : 鍵交換で導出した共有鍵。この共有鍵から暗号化するための鍵を作成する