最近、PPAPとかZip暗号化とかが色々言われているので書きます。
結論 ZipCryptio
と呼ばれる標準の暗号化は脆弱です。7-zipで使えるwzAES
を使いましょう。ただしWindowsの標準機能では復号化できませんが。
暗号化Zipファイルの仕様について
Zipファイルの仕様によれば、Zipファイルは以下のような構造になっています。
[local file header 1]
[encryption header 1]
[file data 1]
[data descriptor 1]
.
.
.
[local file header n]
[encryption header n]
[file data n]
[data descriptor n]
[archive decryption header]
[archive extra data record]
[central directory header 1]
.
.
.
[central directory header n]
[zip64 end of central directory record]
[zip64 end of central directory locator]
[end of central directory record]
ここで関係するのは[local file header]
及び[encryption header]
、[archive decryption header]
です。
local file headerについて
[local file header]
の定義は以下になります。
local file header signature 4 bytes (0x04034b50)
version needed to extract 2 bytes
general purpose bit flag 2 bytes
compression method 2 bytes
last mod file time 2 bytes
last mod file date 2 bytes
crc-32 4 bytes
compressed size 4 bytes
uncompressed size 4 bytes
file name length 2 bytes
extra field length 2 bytes
file name (variable size)
extra field (variable size)
ここで関係するのが、general purpose bit flag
及びcompression method
です。
general purpose bit flagについて
関係ある部分のみ抜き出します。
Bit 0: If set, indicates that the file is encrypted.
Bit 6: Strong encryption. If this bit is set, you MUST
set the version needed to extract value to at least
50 and you MUST also set bit 0. If AES encryption
is used, the version needed to extract value MUST
be at least 51. See the section describing the Strong
Encryption Specification for details. Refer to the
section in this document entitled "Incorporating PKWARE
Proprietary Technology into Your Product" for more
information.
ここで、BIT 0
はすべての暗号化されたファイルで有効になっています。BIT 0
が有効かつBIT 6
が有効な場合、StrongCrypto
と呼ばれる暗号アルゴリズムが用いられれます。BIT 6
が有効でない場合、後述するようにcompression method
に暗号アルゴリズムが入っています。
compression method
この辺りはzipファイルの処理系に大きく依存していますが、たとえば7-zip
(7z
やp7zip
などとも呼ばれる)の場合、以下のドキュメントに記述されています
7-Zip method IDs for 7z and xz archives
関係ある部分を抜き出します。
00 - Copy (not used. Use {00} instead)
01 - Shrink
06 - Implode
08 - Deflate
09 - Deflate64
0A - Imploding
0C - BZip2 (not used. Use {040202} instead)
0E - LZMA (LZMA-zip)
5F - xz
60 - Jpeg
61 - WavPack
62 - PPMd (PPMd-zip)
63 - wzAES
この中で、暗号化に係るのは0x63 - wzAES
です。すなわち、local header
内のcompression method
が0x63
の時は暗号アルゴリズムとしてwzAESが選択されます。それ以外の場合はZipCrypto
と呼ばれる古いアルゴリズムが用いられます。
encryption header について
ZipCrypto
が選択される場合、encryption headerが各ファイルのヘッダ([local file header]
)と[file data]
の間に追加されます。これは128bitの乱数を暗号化したものとなっています。ユーザーが入力したキーはencryption header
の暗号化に用いられ、データ自体の暗号化にはこの128bitの乱数が使われることになります。
6.1.3 Each encrypted file has an extra 12 bytes stored at the start
of the data area defining the encryption header for that file. The
encryption header is originally set to random values, and then
itself encrypted, using three, 32-bit keys. The key values are
initialized using the supplied encryption password. After each byte
is encrypted, the keys are then updated using pseudo-random number
generation techniques in combination with the same CRC-32 algorithm
used in PKZIP and described elsewhere in this document.
6.1.4 The following are the basic steps required to decrypt a file:
1) Initialize the three 32-bit keys with the password.
2) Read and decrypt the 12-byte encryption header, further
initializing the encryption keys.
3) Read and decrypt the compressed data stream using the
encryption keys.
archive decryption headerについて
一方、StrongCryptio
の場合は以下のヘッダがファイル末尾に追加されます。
Value Size Description
----- ---- -----------
0x0017 2 bytes Tag for this "extra" block type
TSize 2 bytes Size of data that follows
Format 2 bytes Format definition for this record
AlgID 2 bytes Encryption algorithm identifier
Bitlen 2 bytes Bit length of encryption key
Flags 2 bytes Processing flags
CertData TSize-8 Certificate decryption extra field data
(refer to the explanation for CertData
in the section describing the
Certificate Processing Method under
the Strong Encryption Specification)
しかし、ZIPのより強力な暗号はPKWARE社が特許を持っていて、エクスプローラーには復号処理が実装されていない。という事なので、Windows エクスプローラでも各種OSSでもStrongCrypto
を復号化することはできないでしょう。
まとめ
ZipCrypto
は暗号キーが実質128bit
しかないので危険。使うならwzAES
を使いましょう。
(StrongCrypto
は多分使えないと思うので)
追記
ZipCryptio
の場合、キーの長さ以前に以下の致命的な脆弱性があるようです。
BIHAM, Eli; KOCHER, Paul C. A known plaintext attack on the PKZIP stream cipher. In: International Workshop on Fast Software Encryption. Springer, Berlin, Heidelberg, 1994. p. 144-153.
追記2 既存Zipファイルの暗号化アルゴリズムの確認方法
$ 7z l -slt file.zip
...snip...
Encrypted = +
...snip...
Method = ZipCrypto Deflate