暗号化されたZipアーカイブからファイルを抽出する場合、ユーザーは元のファイルを読み取るためにパスワードを要求されます。
暗号化されたZipは、ユーザーが正しいパスワードを入力したことをどのように検出しますか?
もちろん、一部のバックエンドサービスには接続せず、比較する実際のパスワードは含まれていません。それでは、どのように正確にチェックしますか?元のパスワードのハッシュがアーカイブに含まれていますか?このハッシュを見つけるのは簡単ですか?
巡回冗長検査(CRC)フィールドは、ファイルが正しく復号化されるかどうかを決定するために使用されます。オリジナルから引用 Zip形式の仕様 :
ヘッダーが復号化された後、Bufferの最後の1または2バイトは、復号化されるファイルのCRCの上位ワード/バイトである必要があり、Intelの低バイト/高バイトの順序で格納されます。 2.0より前のバージョンのPKZIPでは、2バイトのCRCチェックが使用されていました。 2.0以降のバージョンでは、1バイトのCRCチェックが使用されます。これは、提供されたパスワードが正しいかどうかをテストするために使用できます。
更新:Info-Zipの unzip
ソースコード からわかるように、CRC値はパスワードが正しいかどうかを確認するために使用されます。
https://github.com/LuaDist/unzip/blob/master/crypt.c#L617
#ifdef Zip10 /* check two bytes */
c = hh[Rand_HEAD_LEN-2], b = hh[Rand_HEAD_LEN-1];
Trace((stdout,
" (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n",
(ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16),
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff))));
if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ?
((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) :
(ush)(GLOBAL(lrec.crc32) >> 16)))
return -1; /* bad */
#else
b = hh[Rand_HEAD_LEN-1];
Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n",
b, (ush)(GLOBAL(lrec.crc32) >> 24),
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff));
if (b != (GLOBAL(pInfo->ExtLocHdr) ?
((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff :
(ush)(GLOBAL(lrec.crc32) >> 24)))
return -1; /* bad */
#endif
/* password OK: decrypt current buffer contents before leaving */
for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
(int)GLOBAL(csize) : GLOBAL(incnt),
p = GLOBAL(inptr); n--; p++)
zdecode(*p);
return 0; /* OK */
暗号化されたZipは、ユーザーが正しいパスワードを入力したことをどのように検出しますか?
もちろん、一部のバックエンドサービスには接続せず、比較する実際のパスワードは含まれていません。それでは、どのように正確にチェックしますか?
短い答え:ほとんどのZip抽出プログラムはおそらくパスワードをチェックしません。彼らは単にデータを解読しようとし、おそらくそれが実際のデータのように見えるかどうかをチェックします。 Selcukの答えは、一部のプログラムはおそらくファイルに含まれているCRCを使用して、データが正しく復号化されたというある程度の信頼を得るためですが、テキストの「推奨」と「使用可能」から、これはオプションのように聞こえます(ただし、推奨されます) )Zip形式を使用するアプリケーションの場合。
ちなみに、アプリケーションがCRCチェックを無視して暗号化されたZipから何ができるかを抽出し、ユーザーが不正なファイルを見つけることに依存しているため(これは、仕様の残りの部分がどのように記述されているかに応じて、間違ったパスワード)。