SSLやTLSは、ユーザーがWebサイトにアクセスする際に安全な通信を実現する技術である。ユーザーが電子商取引の際に入力するクレジットカード番号などの「漏れては困る情報」をサーバーに安全に送るといった用途で使われている。ユーザーがWebサイトにアクセスする際に、URL▼が「https://」で始まっていたり、URL欄に鍵マークが表示されたりすることで、そのサイトがSSL/TLSに対応していることがわかる。
SSL/TLSでは安全な通信を実現するために「鍵交換」「認証」「共通鍵暗号」「ハッシュ関数」という4種類の暗号技術を使う(図4-1)。それぞれの暗号技術は、複数の方式の中から選んで利用する。例えばTLSの鍵交換だと、「RSA▼」「DHE▼」「ECDHE▼」の中から一つを選んで利用することになる。
こうした4種類の暗号関連技術を組み合わせたものを「暗号スイート」と呼ぶ。暗号スイートには特有の表記がある。「SSLもしくはTLS」「鍵交換」「認証」「前置詞のWITH」「共通鍵暗号▼」「ハッシュ関数▼」をアンダースコア(_)を挟む形で記述する。つまり、暗号スイートの表記を見れば、Part2でいうところの「食材」がわかるようになっている。ただし、RSAは鍵交換と認証の両方に使えるため、鍵交換と認証にRSAを利用している場合は、鍵交換と認証の部分をまとめて「RSA」と記述する。
Part2では、SSLへの攻撃であるPOODLEは暗号通信の手順の問題を悪用していると述べた。この暗号通信の手順に使われている暗号技術が共通鍵暗号である。そこで、まず共通鍵暗号について説明しよう。
共通鍵暗号は、暗号化と復号に同じ鍵を使う暗号方式だ。SSL/TLSで利用する共通鍵暗号には大きく「ストリーム暗号」と「ブロック暗号と暗号利用モードの組み合わせ」がある(図4-2)。ストリーム暗号は、データの流れ(ストリーム)を順次処理していく暗号アルゴリズムだ。代表的なアルゴリズムに「RC4▼」がある。ただし、RC4には脆弱性があるとわかっているので、現在ではほとんど使われていない。
これに対し、ブロック暗号は決まった大きさのデータ、すなわちブロックの単位で暗号化する。現在最もよく使われているブロック暗号のAES▼では、ブロック長は128ビット(16バイト)である。
ブロック暗号で大きいデータを暗号化するときには、データをブロック単位に分け、暗号利用モードと組み合わせて暗号化する。暗号利用モードは、大きいデータをブロック暗号で暗号化する際に安全性を高める仕組みだ。
データをブロック長で分割し、それぞれのブロックをブロック暗号で単純に暗号化する▼と、同じ平文ブロックを暗号化した結果は、必ず同じ暗号文のブロックになる。これでは、攻撃者に解読のヒントを与えることになる。
そこで、一般的な暗号利用モードでは、暗号化の際に複数のデータを組み合わせることで、元の平文を推測しにくくしている。AESと組み合わせる暗号利用モードとしては、CBC▼がよく使われている。実はPOODLEは、SSLでCBCを利用する際の問題を悪用したものだ。
足りない文字分を埋める
どのように悪用したのかを知るために、CBCの具体的な処理を見ていこう(図4-3)。前述したように、ブロック暗号では決まった長さのブロック単位で暗号化を行う。このため、暗号化する文章の最後がブロック長に満たない場合、足りない分を任意もしくは決まった文字で埋める。この文字の並びを「パディング」と呼ぶ。
SSLやTLSの仕様では、パディングの最後のバイトにパディングの長さを示す値を入れることになっている。暗号化する文章の文字数がブロック長のちょうど整数倍だった場合でも、パディング長を表すバイトは必要だ。そこでその場合は、パディングだけのブロックを作って、その最後のバイトにパディング長を入れる。ブロック長が16バイトの場合、パディングだけのブロックの最後のバイトには「15」という値が入ることになる。
CBCでは、ブロック長に分けた平文のデータと「前の暗号結果」との間でXOR▼という演算を行い、そのデータを暗号化して暗号文を作る。ただし、最初のブロックには前の暗号結果はないため、「初期化ベクター▼」という値を用いる。CBCでは初期化ベクターとしてランダムな値を使うことになっている。
このような処理を行うことで、同じ平文を暗号化しても異なる暗号文が生成されるようになる。
パディングが教えてくれる
こうした仕組みをPOODLEがどのように悪用しているのかを見ていこう。攻撃手順は少し複雑だが、処理を順に追っていけば理解できるはずだ。
POODLEのキモは「パディングだけのブロック」だ。攻撃者は、ここに解読したい暗号文のブロックをはめこんで復号を試みる。すると、数百回に1回の割合で復号が成功し、平文を1文字分解読できる。あたかもパディングが神託(オラクル)を与えてくれるように見えるため、こうした攻撃を「パディングオラクル攻撃」と呼ぶ。攻撃者が暗号鍵を知らなくても、パディングが正解を教えてくれるのだ。POODLEの先頭2文字の「PO」は、「Padding Oracle」の略である。
実際の攻撃の手順を見ていこう(図4-4)。図中の「ア」「イ」「ウ」「エ」の部分はそれぞれ重要な役割を果たすデータだ。アとイは既知の値、ウは攻撃が成功したときにわかる値、エは攻撃者が解読しようとする文字を表す。前提として、平文の文字数がちょうどブロック長の整数倍になっており、パディングだけのブロックがあるとする。
攻撃者はまず、パディングだけのブロックを「解読したい暗号文のブロック」に差し替える(図4-4①)。攻撃が成功すると、この暗号文の末尾バイトがわかる。
この状態で復号を行うとたいてい失敗するが、256分の1の確率で成功する(同②)。成功するのは、復号した末尾バイトの値とパディング長の値(ブロック長が16バイトなら15)がたまたま一致する場合。1バイト=8ビットなので、一致する確率は2の8乗分の1、すなわち256分の1である。これくらいの確率であれば、攻撃者が何回も試行することで簡単に成功させられる。
復号に成功した場合、図中のウの値も正しいことになる。この場合、「ウとイの値をXORした値がパディング長(この場合は15)」になる。この関係は「15とイの値をXORした値がウ」と書き直せる▼。イの値はわかるので、これによりウの値が判明する(同③)。
暗号文のコピー元の部分を見ると、アとウの値をXORした値がエになっていることがわかる(同④)。すなわち、平文を1文字分、解読できたことになる。
文字をずらしながらこの手順を繰り返していくことで、平文のまとまった内容を解読できる。
パディングの中身をチェック
Part1では、POODLEの脆弱性はSSLにだけあり、TLSにはないと説明した。このような違いがあるのは、SSLとTLSではパディングの扱いが異なるためだ(図4-5)。
SSLの仕様では、パディング長が正しいかどうかだけをチェックする。例えば、16バイト長のパディングだけのブロックの場合は、末尾が「15」であるかどうかだけをチェックする。パディングの中の値はチェックしない。このため、POODLEでは攻撃者がパディングに任意の値を入れて攻撃できた。
これに対し、TLSの仕様ではパディングのすべてのバイトにパディング長を書き込むことになっている。16バイト長のパディングだけのブロックであれば、すべてのバイトが15になる。
そして「すべてのバイトが15になっているかどうか」をチェックし、そうでなければ復号が失敗する。この状態でPOODLEによる攻撃を行うと、復号した値がたまたまパディングのすべてのバイト(この場合は15)に一致した場合しか復号が成功しなくなる。事実上、TLSではPOODLEによる攻撃は不可能といっていいだろう。
こうした仕様の違いにより、SSLは使われなくなり、TLSへの移行が一気に進んだ。
CBCは廃止の方向に
TLSの現行の最新バージョンはTLS 1.2である。この仕様では、ブロック暗号と暗号利用モードの組み合わせとして、従来の「AES-CBC」に加えて新たに「AES-GCM▼」と「AES-CCM▼」が利用できるようになった。CBCが暗号の機能しか持たないのに対し、GCMやCCMは暗号と認証の両方の機能を備える。そこでAES-GCMやAES-CCMは「認証付き暗号」(AEAD▼)と呼ばれている。AEADは、盗聴防止、改ざん防止、認証のすべての機能を持つ。
さらに次期バージョンのTLS 1.3▼では、AES-CBCが廃止され、AEADだけになる予定である(図4-6)。SSLのPOODLEの温床になったCBC自体が使われなくなる方向だ。なお、TLS 1.3ではストリーム暗号として、米グーグルが推奨する「ChaCha20▼」という新しい暗号方式も使えるようになる見込みである。
RSAも廃止される方向
TLSの仕様で大きく変わろうとしているのは共通鍵暗号だけではない。鍵交換や認証の方式も大きく変わろうとしている。
以前からTLSでは鍵交換と認証の両方の機能を備えるRSAが広く使われていた。RSAは、暗号化と復号に異なる鍵を使う公開鍵暗号の一種である。大きい数の素因数分解が困難であることを安全性の根拠にしている。
ところが、TLSの動向に詳しい明治大学 理工学部 情報科学科 教授の齋藤 孝道氏によると「RSAは使われなくなってきている」という。RSAではいったん秘密鍵が漏れると致命的な影響があるからだ(図4-7)。
RSAでは、Webサーバーに秘密鍵を設定する。この秘密鍵を交換しない限り、TLSによる暗号通信ではいつも同じ秘密鍵が使われる。このため、例えばWebサーバーのハードディスク交換など何らかの理由で秘密鍵が漏洩した場合、それまでのすべての暗号通信を解読できてしまう。攻撃者が暗号化されたデータを収集していると、秘密鍵が漏れた段階ですべての情報が流出してしまうのだ。
そこで、RSAに変わってDHEやECDHEといった鍵交換方式が主流になりつつある。こうした鍵交換方式をまとめてPFS▼と呼ぶ。PFSでは秘密鍵として一時鍵を使う。このため、たとえ秘密鍵が漏れても他の通信の暗号データは復号できず、安全性が高い。
TLS 1.3では、RSAは認証方式としては残るものの、鍵交換方式としては廃止予定。鍵交換方式はPFSに一本化される見込みだ。
実はTLS対応が難しい時期
Webサイトからの情報漏洩などを背景に、TLSの採用は進んでいる(図4-8)。例えば、GoogleやFacebookといった米国の大手サービスでは、既にTLSを全面的に採用している。また、米国では国土安全保障省が連邦政府のすべてのWebサイトにTLS対応を義務付けた。日本でも、中央省庁のWebサイトのTLS対応▼が進んでいないことが問題視されている▼。安全なWebサイトを求める声を背景に、こうしたTLS化の流れは今後ますます強まると考えられる。
ただ、TLSへの対応が急務になっているのにもかかわらず、齋藤氏は「今は実はTLSへの対応が難しいタイミング」と指摘する。ここまでで説明したように、TLSで利用する暗号技術がドラスティックに変わりつつあるからだ。どのバージョンのTLSに対応し、どの暗号スイートを使えばいいかの判断が難しい。
例えば、Webサーバーが新しいバージョンのTLSにしか対応していない▼と、古いバージョンのTLSにしか対応していない端末ではWebページが見えなくなってしまう(図4-9)。そうした端末の中には、新しいTLSに対応するようバージョンアップする手段がないものもある。今後、TLSのバージョンが上がっていくことで、「つながらない端末がどんどん増えていくのではないか」と齋藤氏は懸念する。
Uniform Resource Locatorの略。
Rivest-Shamir-Adlemanの略。
Ephemeral Diffie-Hellmanの略。
Ephemeral Elliptic Curve Diffie-Hellmanの略。楕円曲線を使うようDHEを変更した方式。
この例に示した「AES_128_GCM」は、ブロック暗号としてAESを使い、鍵長が128ビットで、暗号利用モードがGCMであることを示している。
暗号スイートのこの部分に記述するのは、正確にはMAC(Message Autentication Code、メッセージ認証コード)もしくはPRF(PseudoRandom Function、疑似乱数生成器)である。MACやPRFは、それらの内部処理に使っているハッシュ関数の名前で表現することになっている。
Rivest Cipher 4の略。
Advanced Encryption Standardの略。
この暗号利用モードをECB(Electronic CodeBook)という。
Cipher Block Chainingの略。
eXclusive ORの略。排他的論理和。
ストリーム暗号や暗号利用モードの初期値として使われる値。何を初期化ベクターとして使うかは暗号方式によって異なる。
「ウ XOR イ=15」の両辺にイをXORすると「ウ XOR イ XOR イ=15 XOR イ」になる。ある値に同じ値を2回XORすると元に戻るので、「ウ=15 XOR イ」である。
Galois/Counter Modeの略。
Counter with CBC-MACの略。AES-CCMはWPA2で使われているCCMPと同じもの。
Authenticated Encryption with Associated Dataの略。
当初は2016年頃に公開される見込みだったが、改訂作業がどんどんずれ込んでおり、現在は公開時期の見通しが立たない状況である。
RFC 7539として標準化されている。
Perfect Forward Secrecyの略。
記事では「常時SSL化」と表現されている。すべてのWebページをTLS対応にするという意味。
日本経済新聞の2017年12月3日の記事によると、中央省庁のWebサイトのうち、約8割が常時SSL化(TLSに完全対応)していないという。
過去のすべてのバージョンに対応していると運用の負荷がどんどん増えるため、どこかで古いバージョンを見切る必要がある。