
「電子政府における調達のために参照すべき暗号のリスト」では TLS 1.2 の DHE を使えない件
お久しぶりです。新人の H.M. です。
「電子政府における調達のために参照すべき暗号のリスト」に関わる案件があり、DH / DHE 鍵交換について掘り下げて確認した結果、表題の結論になりました。
何を言っているかわからない方も多いと思いますので最初に簡単に説明したうえで、お題の件をネタにTLS 1.2 の鍵交換の概要とセキュリティの状況についてお話したいと思います。
「電子政府における調達のために参照すべき暗号のリスト」とは
「電子政府における調達のために参照すべき暗号のリスト」とは、デジタル庁、総務省及び経済産業省で定めた、電子政府のシステム調達において参照すべき暗号技術のリストです。暗号で使用される技術について安全性を確認し、使用してよいものを規定しています。
また、この中で参照されている「暗号強度要件(アルゴリズム及び鍵長選択)に関する設定基準」(以下、「暗号強度要件」)では暗号技術について鍵の長さ(鍵長)やパラメータなどに応じた強度評価の結果から基準を定め、その利用可否と利用可能な期限を定めています。
これらの内容は暗号技術の基準についてよく吟味されているため、今後を見据えた一般的なセキュリティ確保のリファレンスとしても参考にする価値があります。
何が問題か
TLS 1.2 は現在のインターネットの閲覧の際に使われている暗号通信で最も普及しているプロトコルです。そこで利用できる暗号技術のひとつに Diffie Hellman (DH) 鍵交換というものがあります。今どきのブラウザであれば、インターネットを閲覧する際に普通に利用されています。
一般的に暗号は鍵の長さが長いほど強度が高くなります。「暗号強度要件」では、DH の鍵の長さについても最小値の要件を定めています。
しかし、TLS 1.2 の DH(および DHE:後述します)の仕様では、クライアント側の鍵のビット数はクライアント側で任意に設定できるため、暗号強度の低い通信がおこなわれる可能性があります。
この問題点を理解するために、以降では TLS 1.2 の鍵交換と DH / DHE について説明していきます。
ご興味ございましたらお付き合いください。
鍵交換と RSA
データの暗号化/復号化には鍵が必要です。大量のデータを扱う場合は暗号化と復号化で同じ鍵(共通鍵)を使用する共通鍵暗号が使われます。
しかし、共通鍵暗号で暗号通信をおこなうためには、まず共通鍵を送信側と受信側で共有する必要があります。送受信の双方で共通鍵を安全に共有するための手続きを鍵交換と呼びます。
暗号通信には様々な要素が絡むため、暗号通信を始める前に通信相手との間で通信方法を合意する必要があります。この合意の手続きをネゴシエーションとよび、鍵交換もここに含まれます。ネゴシエーションも含めて、暗号通信の方法をインターネットで共通で利用できるようにするためにするための規格が SSL およびその後継の TLS です。
TLS 1.2 では下記の鍵交換方式が利用できます(後述する一時的な鍵については省いています)。
- RSA
- DH (Diffe-Hellman)
- ECDH (Elliptic Curve Diffie–Hellman : 楕円曲線 Diffie-Hellman)
その中でも、鍵交換で大きな役割を果たしてきたのが RSA という暗号方式で、秘密鍵と公開鍵の2つの鍵のペアを使います。この鍵のペアには下記のような性質があります。
- 片方の鍵で暗号化をおこない、もう片方の鍵で復号化をおこなえます。
- 公開鍵から秘密鍵を作り出すことは困難です。鍵の長さを長くすることで事実上不可能になります。
RSA を使うと、下記の手順で第三者には知られないようにクライアントからサーバに共通鍵を共有できます。
- サーバで RSA の鍵を用意し、公開鍵を公開する
- クライアントが共通鍵の種を生成し、公開鍵を使って暗号化してサーバに送る
- サーバは受信した暗号を秘密鍵で復号化して、共通鍵の種を取り出す
SSL/TLS では初期の頃から公開鍵をサーバ証明書に含めて公開してきました。インターネットブラウザなどのクライアントは pre_master_secret と呼ばれる共通鍵の種を生成してサーバ証明書の公開鍵を使って暗号化し、ClientKeyExchange と呼ばれるメッセージでサーバに送ります。その後、サーバとクライアントは pre_master_secret を元にそれぞれ同じ計算をして実際の共通鍵を生成し、共通鍵暗号で暗号通信をおこないます。
DH (Diffie-Hellman) 鍵交換
SSL/TLS の鍵交換では Diffie-Hellman(DH) というアルゴリズムも使用できます。
DH の計算方法に従って下記をおこなうことで、サーバとクライアントの間で第三者に知られることなく共通鍵を共有できます。
- サーバが素数係数とジェネレータを生成する。
- サーバが秘密鍵A を生成し、秘密鍵A を元に素数係数とジェネレータを使って公開鍵A を計算する
- サーバは公開鍵A、素数係数、ジェネレータを公開する
- クライアントが秘密鍵B を生成し、秘密鍵B を元に素数係数とジェネレータを使って公開鍵B を計算する
- クライアントは公開鍵B を公開する
- サーバは素数係数、秘密鍵A、公開鍵B をもとに共通鍵の種を生成する
- クライアントは素数係数、秘密鍵B、公開鍵A をもとに共通鍵の種を生成する
DH を使うと、サーバが生成した共通鍵の種とクライアントが生成した共通鍵の種は同じものになります。また、秘密鍵A、秘密鍵B は公開されておらず、鍵長が適切であれば公開鍵A、公開鍵B から秘密鍵A や秘密鍵B、共通鍵の種を知ることもできないため、共通鍵の種を第三者が知ることはできません。
素数係数とジェネレータを合わせて DHパラメータと呼ばれることが多いです。DH を使う場合、前述したとおり、サーバはサーバの公開鍵と DHパラメータを公開して、クライアントで受け取れるようにします。
SSL/TLS では RSA と同様に、サーバ証明書に DH の公開鍵等を含めて公開することが可能ですが、実はこのサーバ証明書で公開する方法は現在は一般的ではなく、後述する一時的な鍵によりクライアントに公開鍵等を送る方法が使われています。
DH ではクライアントが生成した公開鍵を ClientKeyExchange メッセージでサーバに送ります。その後、サーバとクライアントは互いに DH のアルゴリズムで共通鍵の種すなわち pre_master_secret を生成して、RSA と同じ手続きで共通鍵を生成します。
TLS 1.2 で使用できるもうひとつの鍵交換アルゴリズムは ECDH (楕円曲線(Elliptic curve) Diffie-Helman) と呼ばれています。計算方法は異なりますが、SSL/TLS のネゴシエーション上は Diffie-Hellman と同じ手続きで鍵共有をおこないます。但し、DH と ECDH で仕様化された経緯が異なり、TLS 1.2 でいくつかの違いがあります。
前方秘匿性(PFS)
鍵交換の秘密鍵が固定されている場合、秘密鍵が漏洩したらどの程度リスクがあるでしょうか。
サーバ証明書の公開鍵で鍵交換をおこなう場合、サーバ証明書を更新しない限りサーバの公開鍵は固定されており、それと対になるサーバの秘密鍵も変更はできません。このとき、もし秘密鍵が外部に知られてしまうと、悪意がある者が現在の暗号化通信を解読できるだけでなく、過去の暗号化通信の記録が保管されていればその内容も解読できてしまう問題があります。
現在の秘密鍵が漏洩しても過去の通信は解読されないことを前方秘匿性(Perfect Forward Secrecy : PFS)と呼びます。PFS に対応するために、鍵交換の際に公開鍵暗号の鍵を毎回新しく生成する方法が使われるようになりました。このような鍵を一時的(Ephemeral)な鍵と呼びます。
実際に暗号化通信を過去にさかのぼって解読できるようにするには、暗号化通信の記録を保持するための膨大なストレージが必要になるため非現実的にも感じられますが、スノーデン事件で米国家安全保障局が大量収集した通信記録を保管している可能性が認識された後は、PFS の必要性が高く見られるようになりました。
TLS 1.2 のネゴシエーションには ServerKeyExchange というメッセージがあり、必要に応じて任意の公開鍵をサーバからクライアントに送ることができます。一時的な公開鍵ではこの ServerKeyExchange メッセージを使用します。
TLS 1.2 の仕様上はそれぞれの鍵交換方式で ServerKeyExchange を使ってサーバから公開鍵を送信できますが、RSA についてはもともと米国の輸出規制に対応するためのものであり、動的な鍵を生成するための時間や鍵の大きさの関係から、実際には RSA での一時的な鍵の送信は使用されていません。
一方、DH および ECDH は一時的な鍵の使用を積極的に利用しており、鍵交換方式としてもそれぞれDHE および ECDHE という名前(後ろに追加された「E」は一時的(Ephemeral)を表す)で区別されています。以降、DH と DHE を合わせて DH(E)、ECDH と ECDHE を合わせて ECDH(E) と表記します。
「暗号強度要件」と DH の暗号強度
冒頭で紹介した「暗号強度要件」の文書では、暗号強度を「ビットセキュリティ」という基準で表しています。
「暗号強度要件」では暗号強度について「NIST SP800-57 Part1」を参照しており、「ビットセキュリティ」は NIST 文書の「security strength (もしくは “bits of security”)」が該当します。「n ビットセキュリティー」というのは「攻撃者がそれを破るために平均して 2^(n-1) 回の操作が必要と推定される」ことを意味しています。
また、「暗号強度要件」ではビットセキュリティの基準に期限を定めて、順次、より強度の高いビット数への移行をおこなっていくよう定めています。具体的には 2030年までの間について、既存システムでは 112ビット以上、新規システムでは 128ビット以上のビットセキュリティを求めています。
DH の暗号強度についての記載を一部抜粋します。
セキュリティ強度 ビット数
112 ビットセキュリティ (L, N) = (2048, 224)
128 ビットセキュリティ (L, N) = (3072, 256)
L は素数係数のビット数、N は秘密鍵のビット数です。
TLS 1.2 の DH(E) の秘密鍵の問題
TLS 1.2 の DH(E) では、鍵のビット数を明示的に規定していません。
TLS 1.2 の DHE ではサーバから ServerKeyExchange メッセージで下記のデータ構造を使って素数係数、ジェネレータ、サーバの公開鍵を送ります。
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams; /* Ephemeral DH parameters */
dh_p が素数係数、dh_g がジェネレータ、dh_Ys がサーバの公開鍵です。
また、DH(E) ではクライアントから ClientKeyExchange メッセージで下記のデータ構造を使ってクライアントの公開鍵を送ります。
struct {
select (PublicValueEncoding) {
case implicit: struct { };
case explicit: opaque dh_Yc<1..2^16-1>;
} dh_public;
} ClientDiffieHellmanPublic;
dh_Yc がクライアントの公開鍵です。
しかし、TLS 1.2 では DH(E) の素数係数、秘密鍵のビット数について定める規定がありません。そこで多くの場合、サーバ側は素数係数とジェネレータをあらかじめ静的にファイルで指定しておく方法が取られています。しかし、秘密鍵の鍵長、特にクライアント側の秘密鍵については規定はなく、サーバ側から制御する方法もありません。
DH(E) の公開鍵から秘密鍵の算出が難しいのは、秘密鍵のビット数に依存しており、このビット数が小さい場合には総当たり攻撃で秘密鍵を見つけ出せる可能性が高くなります。
このため、TLS 1.2 の DH および DHE は「暗号強度要件」の暗号化強度を担保できず、「電子政府における調達のために参照すべき暗号のリスト」の要件に対応できないのです。
TLS 1.2 の ECDH(E)
一方、TLS 1.2 の ECDH(E) では、セキュリティを担保するための規定があります。
ECDH(E) も DH(E) の素数係数やジェネレータに相当するパラメータが存在し、サーバとクライアントで同じパラメータを使って鍵交換をおこないます。
TLS 1.2 の ECDH(E) のパラメータは DH(E) と異なり、仕様書であらかじめ番号を付けたパラメータを決めており、その番号を指定することでサーバとクライアントで同じパラメータを使用するようにしています。この番号は NamedCurve と呼ばれ、ServerKeyExchange でサーバからクライアントに公開鍵を送る際に
併せて送信しています。
NamedCurve で指定できる番号のパラメータは技術的に検証がされているもので、それぞれのビットセキュリティも定められており、サーバ側でどの番号の NamedCurve を許可するか指定できます。このため「暗号強度要件」に従っているパラメータだけに制限することが可能です。
また、TLS 1.2 の ECDH(E) の鍵交換の手続きは「IEEE.P1363」に従うように規定しています。ECDH(E) の秘密鍵の値の範囲はパラメータごとに決まっていて、その中でランダムに選ぶように定められており、これによって秘密鍵の値が偏ることによる暗号強度の低下も起こらないようにしています。
TLS 1.3
TLS 1.3 では DH 鍵交換アルゴリズムもセキュリティを担保する規定に従っています。
更に TLS 1.3 では PFS が必須で、鍵交換は一時的な鍵のみとなりました。すなわち RSA、DH、ECDH は除かれて、DHE および ECDHE のみ使用可能となっています。
TLS 1.2 の ECDH(E) の NamedCurve は TLS 1.3 で拡張され、NamedGroup という項目になりました。DHE のパラメータも仕様化して番号を付けたため、NamedGroup で指定できるようになっています。また、DHE の NamedGroup のパラメータの仕様では秘密鍵の最小ビット数も定めています。このため DHE も NamedGroup の番号ごとのビットセキュリティを確認できるようになり、「暗号強度要件」の要件に従ったパラメータだけを許可することができるようになりました。
TLS 1.3 は鍵交換に限らず TLS 1.2 の仕様を大幅に見直して、簡素かつセキュリティの向上を図ったものとして仕様化されています。既に普及期に入っていますが、今後の更なる普及が期待されます。
まとめ
「電子政府における調達のために参照すべき暗号のリスト」を起点にして、主に TLS 1.2 の鍵交換と DH および DHE について概要を説明してみました。用語も多く足早なためわかりにくさもあったかと思いますが、皆様のご参考になれば幸いです。
それでは楽しいインターネットライフを!
参考文献
- 「電子政府における調達のために参照すべき暗号のリスト」https://www.cryptrec.go.jp/list/cryptrec-ls-0001-2022r1.pdf
- 「暗号強度要件(アルゴリズム及び鍵長選択)に関する設定基準」https://www.cryptrec.go.jp/list/cryptrec-ls-0003-2022r1.pdf
- 「NIST SP800-57 Part1 : Recommendation for Key Management: Part 1 – General」https://csrc.nist.gov/pubs/sp/800/57/pt1/r5/final
- マスタリング TCP/IP SSL/TLS編 [オーム社:Eric Rescorla 著 / 齋藤孝道・鬼頭利之・古森貞 監訳]
- 「RFC 4492 : Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)」https://datatracker.ietf.org/doc/html/rfc4492
- 「RFC 5246 : The Transport Layer Security (TLS) Protocol Version 1.2」https://datatracker.ietf.org/doc/html/rfc5246
- 「RFC 7919 : Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for Transport Layer Security (TLS)」https://datatracker.ietf.org/doc/html/rfc7919
- 「RFC 8446 : The Transport Layer Security (TLS) Protocol Version 1.3」https://datatracker.ietf.org/doc/html/rfc8446
- 「FIPS 186-4 : Digital Signature Standard (DSS)」https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf





