EverQuestできない日記

EverQuestの研究の一環として、活動記録から研究成果や攻略法、ネタばれ情報までいろいろ書いてました。

暗号化 ZIP 書庫 の評価

2008年02月15日 | 暗号
[ PKWARE の伝統的な暗号化 ZIP 書庫 (Traditional PKWARE Encryption) ]


対応ソフトの例
 ZIP32.DLL v2.32 (Info-ZIP)
 ZIP32J.DLL Ver 0.37
 UNZIP32.DLL Ver 5.42
 7-ZIP32.DLL Version 4.57.00.01


仕様:公開、ソース・コードが公開されてます。
 暗号アルゴリズムは Traditional PKWARE Encryption (内部状態サイズ 96bit) というストリーム暗号で平文が内部状態に影響するのが特徴です。10~11バイトの乱数をデータに含めることにより、同じ内容のファイルでも異なる暗号文になります。パスワードから鍵を作るという概念ではなく、パスワードを暗号化することにより内部状態を撹乱してます。


評価、鍵強度:最大96bit、実装上の安全性:×、処理速度:△ (無圧縮なら◎)


 世界的に普及してる ZIP 書庫のパスワード付きのやつです。対応ソフトが非常に多くて、WindowsXP では OS の標準機能になってますし、DLL でも簡単に使えます。DLL を使って ZIP 書庫を操作するためには、ZIP32.DLL と ZIP32J.DLL で圧縮して、UNZIP32.DLL で解凍することになります。7-ZIP32.DLL で ZIP 書庫を扱うこともできますが、互換性はあるもののヘッダー内容が微妙に異なります。また、ZIP 書庫を作るのに同じ Deflate 圧縮方式で圧縮しても、7-ZIP32.DLL は ZIP32.DLL に比べて処理速度が半分ぐらいしかないので、ZIP 書庫だけを扱う場合は ZIP32.DLL の方が使いやすいです。ただし、7-ZIP32.DLL の暗号化 ZIP 書庫は乱数生成方式の弱点がありませんし、4GB 以上のファイルにも対応できます。


 ZIP 書庫の仕様は APPNOTE.TXT を参考にしました。アルゴリズムの詳細は 7-Zip のソース・コードを参考にしました。脆弱性に関しては英語の論文「A Known Plaintext Attack on the PKZIP Stream Cipher (Eli Biham & Paul C. Kocher) 」と「 ZIP Attacks with Reduced Known Plaintext (Michael Stay) 」を参考にしました。最新の ZIP 書庫は RC4 や DES、AES などで暗号化できるのですが、VB から使える DLL がまだ AES 暗号化に対応してないので、古い方式 (Traditional PKWARE Encryption) だけの評価です。乱数生成方式は仕様として決まっていないので、脆弱性の有無は書庫を作るアプリケーションにもよります。




 ZIP 書庫で使われる PKZIPストリーム暗号 (Traditional PKWARE Encryption) は、CRC32 を元にした線形性のある乱数生成器を使っていて、内部状態の拡散性がほとんど無いのが特徴です。そのため、既知平文攻撃に対して非常に弱いそうです。Biham & Kocher の論文によると、暗号化する前の平文の 13バイト (そのうち 8バイトは連続してる必要がある) がわかっていれば、解読することができるそうです。判明してる部分が多いと解読にかかる時間は短くなります。既知平文攻撃を使って解読するシェアウェアのデモ版で試してみましたが、判明してる量が数十~数千バイトもあれば30~40秒で解読できました。ただし、理論的に必要な最低限のバイト数では計算時間が長くて、何日もかかりそうです。Stay の論文では更に改良された鍵推測手法によって、理論的には平文の 4バイトがわかれば解読できるとか。


 しかし逆に言うと「平文 (元のファイル) がわからなければ、現実的な時間では解読できない」ということです。一般的に ZIP 書庫は Deflate 方式で圧縮されてます。ファイルの内容が全てわかっているなら、単純に同じ方式で圧縮すれば平文がばれてしまいます。しかし、ファイル内容の一部だけがわかってる、あるいは一部だけ予測できるというぐらいなら、そのファイルを圧縮した後にどうなるかは予測不可能です。拡張子から元のファイルが Word 文章だとか JPEG 画像だとかばれても、そのファイル・フォーマットのヘッダーなどの固定領域が Deflate 圧縮した後にどうなるかはわからないので、既知平文攻撃することもできないという訳です。


 既知平文攻撃を防ぐためには、「Deflate など圧縮結果が予測できない方式で圧縮する」ことが大切です。また、「圧縮前のファイル」や「圧縮したが暗号化されてないファイル」と「圧縮暗号化された後のZIP書庫ファイル」の組を攻撃者が入手すると、同じパスワードで圧縮暗号化した全ての ZIP 書庫が解読されてしまいます。暗号化 ZIP 書庫を作る際には、書庫の中に一般的に入手しやすいファイルを絶対に含めないようにする必要があります。暗号化されていてもファイル名はわかるので、OS や一般的なアプリケーションの構成ファイルや、ネットで配布されてる DLL など内容がわかるファイルがあれば、攻撃者もそれを入手して解読することができるという訳です。


 ZIP 書庫でパスワードを使って暗号化する際には、既知平文攻撃を使われないように注意しましょう。暗号化 ZIP 書庫を作る際には圧縮レベルを 0 (無圧縮) にすると危険で、必ず圧縮してから暗号化するようにしましょう。暗号化 ZIP 書庫には内容がわかるファイルを含めないようにしましょう。




 Stay の論文によると、一部のアプリには乱数の実装方法に弱点があります。PKZIP 1.0 / 2.0 互換の InfoZIP や WinZip バージョン 8.0 以前は、乱数を含む暗号ヘッダーを解析して内部状態を探ることができるそうです。その場合、同じパスワードで暗号化されたファイルが 5個あれば、Pentium 2 500MHz のパソコンで 2時間ぐらいあれば解読できるそうです。乱数生成の弱点を使って解読するシェアウェアの説明書によると、WinZip 8.0 以前で圧縮暗号化された書庫なら一時間以内に解読できるとか。一般的に ZIP 書庫には複数のファイルやフォルダが含まれることが多く、暗号化した際には全てが同じパスワードになるので、このファイルが 5個必要という前提条件は成立しやすいです。やっかいなことに、個々の圧縮アプリケーションでこの脆弱性があるかはソース・コードを確かめないとわかりません。安全性が確認できてない圧縮アプリケーションを使う場合は、書庫に格納するファイルやフォルダの数に気をつける必要があります。


 乱数生成方式の脆弱性が修正されたアプリケーションを使いましょう。InfoZIP 互換の ZIP 圧縮用 DLL (ZIP32.DLL や ZCRYPT32.DLL) や zlib 付属の minizip を使って暗号化する場合はファイルの数を 4個以下にするべきです。7-ZIP32.DLL で作った暗号化 ZIP 書庫にはこの弱点がないので、5個以上のファイルを暗号化するなら 7-ZIP32.DLL を使いましょう。




 暗号化 ZIP 書庫はファイルの内容は暗号化されるものの、ファイル名やサイズ、CRC が記録されてるヘッダーは暗号化されません。したがって、ファイル・サイズが非常に小さい場合は、CRC からオリジナルのファイルを逆算することができます。ただし、同じ CRC になる逆算結果は無数に存在するため、あらかじめファイルの書式や一部が判明してる必要があります。テキスト形式で文字コードは何とか JPEG 画像であるとか。


 CRC からファイルを逆算できるのは非常に小さいファイルに限られますが、上記の既知平文攻撃によって、圧縮前のファイルがばれると同じパスワードで暗号化した他の全てのファイルも解読されます。ただし、圧縮前のファイルを元に既知平文攻撃するためには圧縮後のファイル・サイズが 13バイト以上必要なので、ファイルの内容や圧縮率によっては既知平文攻撃できないかもしれません。


 注意点として、暗号化してあっても CRC からファイルの内容を逆算できます。数バイト程度の小さいファイルは CRC から逆算されてしまうので、暗号化する意味はほとんど無く、逆に他のファイルを解読する手助けになってしまう可能性があります。




 一般的な暗号化 ZIP 書庫のパスワード解析アプリケーションは、パスワードに対する総当り攻撃を行います。この攻撃方法はパスワードの長さが短い場合や部分的にパスワードを覚えてたり文字の種類がわかってる時には非常に効果的で、ほとんどのパスワード回復アプリケーションがこの機能を備えています。しかし、パスワードが長くなるほど現実的な時間では解読できなくなります。一方で、PKZIPストリーム暗号 (Traditional PKWARE Encryption) の内部状態のサイズは 96bit なので、パスワードがどれだけ長くても実質的な強度は 96bit 以下に制限されます。1バイトの中に文字として使えるのは 6bit (BASE64がそう) ぐらいなので、パスワードは半角英数の 1バイト文字で 16 文字ぐらいが限界で、それ以上の長さにしても暗号の強度的には変わりません。パスワードのパターンが 2 の 96 乗以上であることがわかってるならば、パスワードではなく内部状態を総当りで試した方が効率がいいからです。また、異なるパスワードでも結果的に同じ内部状態になるので、せっかく長いパスワードで暗号化したとしても、その長いパスワードとは異なる短いパスワードで復号できる可能性があります。


 パスワードは長い方が安全ですが、長すぎても効果はありません。総当り攻撃に対してはパスワードは半角英数で 16文字あれば充分です。半角英数 1文字で 6bit 相当のパターンとすると、DES と同程度の総当り攻撃耐性 (個人では解読困難) を実現するには最低でも 10文字必要です。


最新の画像もっと見る