[インデックス 16601] ファイルの概要
このコミットは、Go言語の crypto/tls
パッケージにおける、TLS (Transport Layer Security) ハンドシェイク時にクライアントがサーバーに提示する暗号スイートの優先順位を変更するものです。具体的には、楕円曲線ディフィー・ヘルマン鍵交換 (ECDHE) を使用する暗号スイートをプレーンなRSA鍵交換よりも優先させ、また、Lucky13攻撃への対策としてRC4暗号スイートをAES暗号スイートよりも優先させるように順序が調整されています。
コミット
commit 966e889687095f33239314d2e7e03c7f3ac3b0c3
Author: Adam Langley <agl@golang.org>
Date: Wed Jun 19 16:46:53 2013 -0400
crypto/tls: change advertised ciphersuite order.
TLS clients send ciphersuites in preference order (most prefereable
first). This change alters the order so that ECDHE comes before plain
RSA, and RC4 comes before AES (because of the Lucky13 attack).
This is unlikely to have much effect: as a server, the code uses the
client's ciphersuite order by default and, as a client, the non-Go
server probably imposes its order.
R=golang-dev, r, raggi, jsing
CC=golang-dev
https://golang.org/cl/10372045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/966e889687095f33239314d2e7e03c7f3ac3b0c3
元コミット内容
このコミットは、Go言語の crypto/tls
パッケージにおいて、TLSクライアントがサーバーに提示する暗号スイートの順序を変更することを目的としています。変更の主な理由は以下の2点です。
- ECDHEの優先: プレーンなRSA鍵交換よりもECDHE (Elliptic Curve Diffie-Hellman Ephemeral) を使用する暗号スイートを優先させます。ECDHEは前方秘匿性 (Forward Secrecy) を提供するため、よりセキュアな選択肢とされています。
- RC4の優先 (Lucky13攻撃対策): Lucky13攻撃への対策として、AES (Advanced Encryption Standard) を使用する暗号スイートよりもRC4 (Rivest Cipher 4) を使用する暗号スイートを優先させます。
コミットメッセージでは、この変更が実際に大きな影響を与える可能性は低いと述べられています。サーバーとして動作する場合、GoのTLS実装はデフォルトでクライアントの暗号スイート順序を使用するためです。また、クライアントとして動作する場合、Go以外のサーバーは独自の暗号スイート順序を強制する可能性が高いからです。
変更の背景
この変更の背景には、TLS/SSLプロトコルにおけるセキュリティの進化と、特定の暗号アルゴリズムに対する脆弱性の発見があります。
1. 前方秘匿性 (Forward Secrecy) の重要性
TLSハンドシェイクにおいて、鍵交換アルゴリズムはセッション鍵を確立するために使用されます。従来のRSA鍵交換では、サーバーの長期的な秘密鍵が漏洩した場合、過去の通信もすべて復号されてしまうという問題がありました。これを「前方秘匿性がない」と呼びます。
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) は、セッションごとに一時的な鍵ペアを生成する鍵交換アルゴリズムです。これにより、たとえサーバーの長期的な秘密鍵が漏洩したとしても、過去の通信のセッション鍵は復元できないため、通信内容が保護されます。これを「前方秘匿性がある」と呼び、現代のセキュアな通信においては非常に重要な特性とされています。このコミットは、よりセキュアなECDHEを優先することで、GoのTLS実装のセキュリティレベルを向上させることを意図しています。
2. Lucky13攻撃への対策
2013年に発表された「Lucky13攻撃」は、TLSのCBC (Cipher Block Chaining) モードにおけるパディングオラクル攻撃の一種です。この攻撃は、TLSのMAC-then-Encrypt (MACを計算してから暗号化する) 構造と、特定のタイミング攻撃を利用して、暗号化された通信内容を推測する可能性がありました。AESは通常CBCモードで使用されることが多く、この攻撃の影響を受けやすいとされていました。
一方、RC4はストリーム暗号であり、CBCモードのようなパディングを使用しないため、Lucky13攻撃の影響を受けません。このコミットは、Lucky13攻撃の脅威を回避するための一時的な対策として、AES-CBCよりもRC4を優先するように暗号スイートの順序を変更しました。ただし、RC4自体にも他の脆弱性(例えば、RC4 Bias Attackなど)が後に発見され、現在では非推奨の暗号アルゴリズムとなっています。このコミットが作成された時点では、Lucky13攻撃への対策が喫緊の課題でした。
これらの背景から、GoのTLS実装は、よりセキュアな鍵交換アルゴリズムと、当時問題となっていた攻撃に対する耐性を考慮して、暗号スイートの優先順位を見直す必要がありました。
前提知識の解説
このコミットを理解するためには、以下のTLS/SSLおよび暗号技術に関する基本的な知識が必要です。
1. TLS (Transport Layer Security)
TLSは、インターネット上で安全な通信を行うための暗号化プロトコルです。ウェブブラウザとウェブサーバー間のHTTPS通信などで広く利用されています。TLSは、通信の盗聴、改ざん、なりすましを防ぐための機能を提供します。
TLSハンドシェイクは、クライアントとサーバーが通信を開始する際に、互いの身元を確認し、使用する暗号アルゴリズムや鍵を決定するプロセスです。
2. 暗号スイート (Cipher Suite)
暗号スイートは、TLS通信で使用される一連の暗号アルゴリズムの組み合わせを定義するものです。通常、以下の要素を含みます。
- 鍵交換アルゴリズム (Key Exchange Algorithm): クライアントとサーバーがセッション鍵を安全に共有するための方法(例: RSA, DHE, ECDHE)。
- 認証アルゴリズム (Authentication Algorithm): サーバー(およびオプションでクライアント)の身元を証明する方法(例: RSA, DSA, ECDSA)。
- 共通鍵暗号アルゴリズム (Symmetric Encryption Algorithm): 実際のデータ暗号化に使用されるアルゴリズム(例: AES, RC4, 3DES)。
- メッセージ認証コード (MAC) アルゴリズム (Message Authentication Code Algorithm): メッセージの完全性と認証を保証するためのハッシュ関数(例: SHA1, SHA256)。
暗号スイートは通常、TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
のような形式で表記されます。これは、「TLSプロトコルを使用し、鍵交換にECDHE、認証にRSA、共通鍵暗号にAES-128-CBC、MACにSHA1を使用する」という意味です。
3. 鍵交換アルゴリズム: RSA vs. ECDHE
-
RSA (Rivest-Shamir-Adleman):
- 公開鍵暗号方式の一つで、鍵交換とデジタル署名に広く使われます。
- TLSでは、サーバーの公開鍵でセッション鍵を暗号化し、サーバーの秘密鍵で復号することでセッション鍵を共有します。
- 前方秘匿性がない: サーバーの秘密鍵が漏洩すると、その秘密鍵で暗号化された過去のすべての通信が復号されてしまいます。
-
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral):
- 楕円曲線ディフィー・ヘルマン鍵交換の「一時的 (Ephemeral)」バージョンです。
- セッションごとに新しい一時的な鍵ペアを生成し、それらを使ってセッション鍵を導出します。
- 前方秘匿性がある: セッション鍵は一時的な鍵ペアから生成されるため、サーバーの長期的な秘密鍵が漏洩しても、過去の通信のセッション鍵は復元できません。これにより、通信の機密性が長期的に保護されます。
4. 共通鍵暗号アルゴリズム: RC4 vs. AES-CBC
-
RC4 (Rivest Cipher 4):
- ストリーム暗号の一種で、データをバイト単位で暗号化します。
- シンプルで高速なため、かつては広く使われました。
- パディングを使用しないため、パディングオラクル攻撃の影響を受けません。
- しかし、鍵スケジューリングの脆弱性や、特定の鍵ストリームのバイアスが発見され、現在ではセキュリティ上の問題があるため非推奨とされています。
-
AES (Advanced Encryption Standard) - CBC (Cipher Block Chaining):
- ブロック暗号の一種で、データを固定長のブロックに分割して暗号化します。
- CBCモードは、前のブロックの暗号文を次のブロックの平文とXORすることで、同じ平文ブロックが同じ暗号文ブロックにならないようにします。
- データの長さがブロックサイズの倍数でない場合、パディング(詰め物)が必要です。
- Lucky13攻撃: TLSのCBCモードにおけるパディング処理の脆弱性を利用したタイミング攻撃です。攻撃者は、サーバーがパディングエラーを報告するタイミングの違いを観測することで、暗号化されたデータを推測する可能性があります。
5. Lucky13攻撃
Lucky13攻撃は、TLSのCBCモードにおけるパディングオラクル攻撃の一種です。TLSプロトコルでは、MAC (Message Authentication Code) を計算してから暗号化する「MAC-then-Encrypt」という構造が採用されています。攻撃者は、暗号化されたメッセージをサーバーに送信し、サーバーがそのメッセージを復号・検証する際の処理時間(特にパディングの検証時間)のわずかな違いを観測します。この時間の違いから、パディングが正しいかどうか、ひいては元の平文の一部を推測することが可能になります。
この攻撃は、特にAES-CBCのようなブロック暗号のCBCモードに影響を与えます。RC4のようなストリーム暗号はパディングを使用しないため、この攻撃の影響を受けません。
技術的詳細
このコミットは、Go言語の crypto/tls
パッケージ内の cipher_suites.go
ファイルを変更し、cipherSuites
というグローバル変数で定義されている暗号スイートのリストの順序を調整しています。このリストは、GoのTLSクライアントがサーバーに提示する暗号スイートの優先順位を決定します。
TLSハンドシェイクの「ClientHello」メッセージでは、クライアントは自身がサポートする暗号スイートのリストを優先順位付きでサーバーに送信します。サーバーは、このリストの中から自身もサポートしており、かつクライアントが最も優先する暗号スイートを選択して通信を確立します。
変更の具体的な技術的意図は以下の通りです。
-
前方秘匿性 (Forward Secrecy) の強化:
TLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
これらのECDHEベースの暗号スイートが、従来のRSAベースの暗号スイート(例:TLS_RSA_WITH_RC4_128_SHA
,TLS_RSA_WITH_AES_128_CBC_SHA
)よりもリストの先頭に移動されました。これにより、GoのTLSクライアントは、サーバーがECDHEをサポートしている場合、前方秘匿性を提供するよりセキュアな接続を確立しようと試みます。
-
Lucky13攻撃への一時的な対策:
TLS_RSA_WITH_RC4_128_SHA
がTLS_RSA_WITH_AES_128_CBC_SHA
よりも前に配置されました。- 同様に、ECDHEベースのスイートでも
TLS_ECDHE_RSA_WITH_RC4_128_SHA
がTLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
よりも前に配置されました。 これは、Lucky13攻撃がAES-CBCのようなブロック暗号のCBCモードに影響を与えるのに対し、RC4はストリーム暗号でありパディングを使用しないため、この攻撃の影響を受けないという特性を利用したものです。当時、Lucky13攻撃が活発に議論されていたため、一時的な回避策としてRC4を優先することで、攻撃のリスクを低減しようとしました。
コミットメッセージにもあるように、この変更が実際に大きな影響を与える可能性は低いとされています。
- サーバー側: GoのTLSサーバーは、デフォルトでクライアントが提示する暗号スイートの順序を尊重します。そのため、クライアントがGo以外の実装であれば、そのクライアントの優先順位が適用されます。
- クライアント側: GoのTLSクライアントがGo以外のサーバーに接続する場合、サーバーは自身の暗号スイートの順序を強制する(サーバーが提示されたリストの中から自身の優先順位に基づいて選択する)ことが一般的です。
しかし、この変更は、GoのTLS実装が当時の最新のセキュリティ勧告と脆弱性情報に対応しようとする姿勢を示しています。暗号スイートの順序は、セキュリティとパフォーマンスのバランスを考慮して常に最適化されるべきであり、このコミットはその一環として行われました。
コアとなるコードの変更箇所
変更は src/pkg/crypto/tls/cipher_suites.go
ファイルに集中しています。
--- a/src/pkg/crypto/tls/cipher_suites.go
+++ b/src/pkg/crypto/tls/cipher_suites.go
@@ -52,14 +52,16 @@ type cipherSuite struct {
}
var cipherSuites = []*cipherSuite{
+// Ciphersuite order is chosen so that ECDHE comes before plain RSA
+// and RC4 comes before AES (because of the Lucky13 attack).
+{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
+{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
+{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
-{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1},
-{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
-{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
-{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},\n+\t{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},\n}
コアとなるコードの解説
変更の中心は、cipherSuites
という *cipherSuite
型のスライス(Goにおける動的配列)の初期化部分です。このスライスは、GoのTLS実装がサポートする暗号スイートのリストと、それらの優先順位を定義しています。リストの上にあるものほど優先度が高いと見なされます。
具体的な変更点は以下の通りです。
-
ECDHEベースの暗号スイートの移動:
- 以前はリストの中盤にあった
TLS_ECDHE_RSA_WITH_RC4_128_SHA
,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
の3つの暗号スイートが、リストの先頭に移動されました。 - これにより、GoのTLSクライアントは、これらの前方秘匿性を提供する暗号スイートを最も優先してサーバーに提示するようになります。
- 以前はリストの中盤にあった
-
RC4ベースの暗号スイートの優先:
- ECDHEベースのスイート内でも、
TLS_ECDHE_RSA_WITH_RC4_128_SHA
がTLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
やTLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
よりも前に配置されました。 - 同様に、RSAベースのスイートでも、
TLS_RSA_WITH_RC4_128_SHA
がTLS_RSA_WITH_AES_128_CBC_SHA
やTLS_RSA_WITH_AES_256_CBC_SHA
よりも前に配置されています。 - これは、Lucky13攻撃がAES-CBCに影響を与えるため、一時的にRC4を優先するという意図に基づいています。
- ECDHEベースのスイート内でも、
-
TLS_RSA_WITH_3DES_EDE_CBC_SHA
の位置変更:- このスイートは、RSAベースのスイート群の最後に移動されました。3DESはAESに比べてセキュリティ強度が低いとされており、優先度を下げるのは妥当な変更です。
これらの変更により、GoのTLSクライアントは、よりセキュアな前方秘匿性を提供するECDHEベースの暗号スイートを優先し、かつ当時のLucky13攻撃の脅威を考慮してRC4ベースのスイートを一時的に優先するようになりました。これは、セキュリティ上のベストプラクティスと、既知の脆弱性への対応を反映したものです。
関連リンク
- Lucky13攻撃に関する論文:
- https://www.isg.rhul.ac.uk/tls/TLStiming.pdf (The Lucky Thirteen Attack on TLS)
- 前方秘匿性 (Forward Secrecy) について:
- TLS暗号スイートについて:
参考にした情報源リンク
- Go言語のコミット履歴: https://github.com/golang/go/commit/966e889687095f33239314d2e7e03c7f3ac3b0c3
- TLS/SSLおよび暗号技術に関する一般的な知識(Wikipedia, RFCなど)
- Lucky13攻撃に関するセキュリティ研究論文
- 前方秘匿性に関するセキュリティ記事I have generated the detailed technical explanation in Markdown format, following all the specified instructions and chapter structure. The output is ready to be printed to standard output.