エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

意味不明な文字列(例:ECDHE-ECDSA-CHACHA20-POLY1305)ことCipher Suiteと鍵交換について

【セキュリティチームブログリレー1回目】

こんにちは。エンジニアリンググループの山本です。

少し前にはメール送信についての記事をSREとして書かせていただいています。 www.m3tech.blog

私はSREとしてメール管理やサーバ管理をさせていただいておりますが、その傍らなのか本業なのかわかりませんがセキュリティチームと呼ばれるバーチャルチームでプロダクトセキュリティについても担当させていただいています。

その中で毎日お付き合いさせていただいているTLSに関連して「Cipher Suite(暗号スイート)」とその中の一部である「鍵交換」と呼ばれるものについて書かせていただきたいと思います。

Cipher Suite

OpenSSL と Cipher Suite

OpenSSLをインストールした環境では、次のようなコマンドを実行するとよくわからないものがでてきます。 噂には聞いたことがあるかもしれませんが、これがCipher Suiteと呼ばれるものです。

$ openssl ciphers -v
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=ChaCha20-Poly1305 Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=RSA  Enc=ChaCha20-Poly1305 Mac=AEAD
DHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=DH       Au=RSA  Enc=ChaCha20-Poly1305 Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH       Au=RSA  Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256   TLSv1.2 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA256
DHE-RSA-AES256-SHA      SSLv3 Kx=DH       Au=RSA  Enc=AES(256)  Mac=SHA1
GOST2012256-GOST89-GOST89 SSLv3 Kx=GOST     Au=GOST01 Enc=GOST-28178-89-CNT Mac=GOST89IMIT
DHE-RSA-CAMELLIA256-SHA256 TLSv1.2 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA256
DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH       Au=RSA  Enc=Camellia(256) Mac=SHA1
GOST2001-GOST89-GOST89  SSLv3 Kx=GOST     Au=GOST01 Enc=GOST-28178-89-CNT Mac=GOST89IMIT
AES256-GCM-SHA384       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(256) Mac=AEAD
AES256-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA256
AES256-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(256)  Mac=SHA1
CAMELLIA256-SHA256      TLSv1.2 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA256
CAMELLIA256-SHA         SSLv3 Kx=RSA      Au=RSA  Enc=Camellia(256) Mac=SHA1
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
(省略)

この文字化けのような文字列、ECDHE-RSA-AES256-GCM-SHA384 とか AES256-SHA というのがそれです。OpenSSLの命名がそれだというだけで、別の記法も存在します。例えば前者は TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 となり、後者は TLS_RSA_WITH_AES_256_CBC_SHA となります。どちらの記法でも良いのですが、OpenSSLの命名の場合は特に RSA を省略しがちという特徴があるので、その部分だけ気にした方が良さそうです。

openssl ciphers -V で実行すると、それぞれのCipher Suiteに対応する数値(ex. 0xC0,0x30) がでてきますので、その値を見ればもう一つの名前との対応をつけることができます。

www.iana.org

Cipher Suiteの構成要素

Cipher SuiteとはTLS(SSL)で利用する各種技術の組み合わせです。「各種技術」というのは次の4つです。

  • 鍵交換(Key Exchange : Kx)
  • 認証(Authentication : Au)
  • 暗号化(Encryption : Enc)
  • メッセージ認証(Message Authentication Code : Mac)

先ほどの ECDHE-RSA-AES256-GCM-SHA384で言えば次のような意味と言えます。

  • 鍵交換には ECDHEを利用
  • 認証には RSAを利用
  • 暗号化にはAES256を利用しGCMモードを利用
  • メッセージ認証にはSHA384を利用

Cipher Suite完全に理解した!の図

ちょっと複雑なのですが、GCMモードというのは暗号化と共にメッセージ認証を実施することができるものですので、暗号化とメッセージ認証は渾然一体となっています。

大まかにいうと「公開鍵暗号を利用するKxとAu」「共通鍵暗号を利用するEncとMac」の組み合わせで働くと考えれば分かりやすそうです。

この記事では「鍵交換」に注目してその説明をしたいと考えていますが、一応簡単に全体の概要を書いてみます。

  • 公開鍵暗号を利用
    • 鍵交換 : 鍵情報を通信相手と安全に共有(ex. ECDHE, RSA)
    • 認証:いわゆる電子署名を用いて相手が正しいことを確認(ex. RSA)
  • 共通鍵暗号を利用
    • 暗号化:傍受されないように平文を変換(ex. AES, 3DES)
    • メッセージ認証:メッセージが改ざんされていないことを確認(ex. SHA1, SHA384)

TLSの大雑把な流れ

TLSのやりとりについて細かく記述することはしませんが、大まかに言えば「相手が正しいことを検証しつつ、暗号化で利用する『鍵情報』を安全に相互共有」するのが当初のTLSのネゴシエーションで行われていることで、ここが公開鍵暗号で実施されている「鍵交換」と「認証」です。 そしてそこで共有された「鍵情報」を利用して暗号化して情報を送受信し、さらにメッセージが改竄されていないことを検証するところがその後の通信で行われていることとなります。メッセージ認証は古典的な方法ですと「メッセージと共通鍵からハッシュをとってメッセージと共にハッシュを送信し、受信側で同じくメッセージと共通鍵からハッシュをとって送られてきたハッシュとの一致を見る」というようなことを実施します。

鍵交換とは

さて、今回の本丸である「鍵交換」です。 先ほど既に少しだけ触れましたが、「なんらかの方法を使って」相手と同じ鍵を共有することができればゴールです。

その「なんらかの方法」にも各種あるので、それごとに流派があるわけです。

RSA鍵交換

「公開鍵暗号といえばRSA」というくらいにRSAは非常に有名です。ただ、実はRSAは少々特殊な仕組みです。それはRSAが鍵交換と認証、両方の機能を有しているためです。

  • RSA鍵交換
  • RSA認証(電子署名)

この二つはごっちゃになりやすいのですが、実はあまり関係ありません。

RSAとは巨大素数の素因数分解が難しいという性質を利用して…のような話は各所で説明されており、この性質を利用して平文を暗号化したり、あるいは文書に対する署名を作成します。

RSA鍵交換は比較的簡単です。送受信者(AliceとBob)の間で使われる共通鍵であるセッション鍵と呼ばれるものをAliceが作成します。AliceはBobの公開鍵でセッション鍵をRSAの方式で暗号化して送信し、BobはBobの秘密鍵でRSAの方式によって復号します。実際はもう少し複雑なこともやっていますが、根本はこの通りです。

RSA鍵交換

なるほど、こうやればBobしかセッション鍵を復号できないから安心だよね。ということになります。 なお、Bobの公開鍵が偽物であったら困りますので、この公開鍵が正しいことを証明するために電子署名が行われています。つまり、鍵交換は電子署名とペアになって用いられることで安全に働きます。

RSA鍵交換の現在

「なるほど。RSA鍵交換理解した!世の中のTLS/SSLではこうやって動いてるんだね!SSHもかな?」と思うかもしれません。

実はそんなことはなかったりします。そのような方式は現在はほぼ取られていません。

言い方を変えると先述のCipher SuiteにおいてKxにRSAが来るような方式(ex. AES256-SHA256)は現在ではほとんど使われないのです。

これはRSA鍵交換が脆弱であるためです。

全く用いられていないというわけではなく、古いクライアントなどがどうしてもRSA鍵交換にしか対応していないという問題はあり得ます。 ただ通常のブラウザや新しいツールは既に新しい方式に対応していますので、脆弱な方式であるRSA鍵交換はできるだけサーバ側で無効化することが望ましいと言えます。 また、RSA鍵交換に限らず古い方式をサポートしたままにしておくとダウングレード攻撃(あえて脆弱な方式で接続してくる)の目標になってしまいますので、ご注意ください。

$ curl -v https://www.google.com/ 2>&1 | egrep TLS
* SSL connection using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

例えば、curlを使ってGoogleに接続してみたところ、Kxの部分にはRSAではなくECDHEと呼ばれる方法が使われていることがわかります。

ブラウザで調べるならば、例えばChromeならばデベロッパーツールのSecurityタブから確認できます。この場合は鍵交換はX25519を使っている模様です。(X25519はECDHEの一種です。)

GoogleにChromeで接続した場合のCipher Suite

SSHについてですが、SSH1ではRSA鍵交換が利用されていたと聞きます。しかし既に使われていないでしょうから廃止済と言っても良さそうです。SSHの鍵ペア生成ではRSAを指定することも多いと思いますが、これは鍵交換の話ではないということをご承知下さい。

TLSについてもTLS 1.3ではRSA鍵交換は廃止されますので、今後は消えていくことでしょう。

DH鍵交換

では、RSA鍵交換を使わないならばどうやって鍵交換をしているのかということになりますが、Cipher Suiteの一覧にはECDH、あるいはDHと呼ばれるものが並んでいるのが見えます。こちらが現在の主流方式であるDH方式(Diffie-Hellman方式)です。

DH鍵交換にはDH、DHE、ECDH、ECDHEと各種ありますが基本的なフローは同一です。セッション鍵を送付することなく互いに同一のセッション鍵を作り上げるという数学的なトリックを使います。

ここでは例によって数学的な細かなことは書きません(正確にいえば、私が説明をすると不正確になってしまうかもしれませんので書けません)が、大まかにいうと次の形です。

  • AliceとBobはお互いに秘密鍵(数値)を決める、また特定の計算方法を共有する
  • Aliceは秘密鍵と上記計算方法によって得た数値を公開鍵とし、Bobに送る
  • Bobは秘密鍵と上記計算方法によって得た数値を公開鍵とし、Aliceに送る
  • Aliceは秘密鍵とBobから送信されてきた公開鍵を利用して計算しセッション鍵を生成する
  • Bobは秘密鍵とAliceから送信されてきた公開鍵を利用して計算しセッション鍵を生成する

DH鍵交換

最終的に得られるセッション鍵(共通鍵)が一致してしまうので、セッション鍵を送付する必要はないのです。 具体的な計算方法は各種サイトで紹介されているので参照してください。 この場合も送られてきた公開鍵が正しいことはDH鍵交換自体は何も担保してくれませんので別途RSA署名などで担保する必要があります。

実際のセキュリティ運用において

実際に運用するにあたっては、DH鍵交換だからどうしたとか、RSA鍵交換だからどうしたという技術の中身そのものをあまり気にする必要はありません。

Cipher Suite選択(サーバで何を有効化するか)においては、大抵次のような法則だけ覚えておけば、自ずと新しいもののみが残ります。

  • RSA鍵交換を無効化(RSA認証(電子署名)はOK)
  • DESや3DES、RC4などを無効化
  • CBCモードを無効化(GCMモードを使う)
  • SHA1やMDを無効化

TLSに関しては1.3になれば、そもそもに使えるCipher Suiteの種類が非常に小さくなるのでそれほど気にしなくても良くなりますが、TLS 1.2がなくなる日はまだまだ先でしょうからこのわけのわからない組み合わせと戦い続ける日々は続きそうです。

ちなみに、この記事のタイトルになっているCHACHA20やPOLY1305は変わった名前のように思えますが、新しいEnc(CHACHA20)+Mac(POLY1305)の方式です。今後はこの組み合わせもよく見かけるようになるかもしれません。

まとめ

  • Cipher Suiteは鍵交換、認証、暗号化、メッセージ認証の組み合わせである
  • RSA鍵交換と呼ばれる鍵交換方式があるが現在は廃れている(RSAによる電子署名の認証・検証は健在)
  • DH鍵交換とその進化形が現在の主流であり、これは数学的なトリックを利用して相手の公開鍵と自己の秘密鍵から互いに同一の鍵を得るもの
  • 古い方式は可能な限り排除していこう!

暗号理論の分野は奥が深いと思いますが、もしも「この部分不正確だよ」というような箇所がありましたら、是非ご指摘ください。

We are Hiring!

エムスリーではセキュリティに興味のあるエンジニアも求めております。

実際の業務において鍵交換について語る機会は全くないのではないかと思いますが、 クラウド・オンプレのセキュリティ強化、コードの監視、その他多岐にわたるセキュリティ向上の取り組みに少しでも関心があるようでしたら、是非ご連絡ください。

open.talentio.com open.talentio.com jobs.m3.com