Python 仅当我将 "D" 作为密码传递时才会抛出 "zipfile.BadZipFile: Bad CRC-32"

Python throws "zipfile.BadZipFile: Bad CRC-32" ONLY when I pass "D" as password

我正在尝试创建一个 Python 脚本来测试受密码保护的 zip 文件的密码。唯一的问题是,每当我尝试专门传递 "D" 作为密码时,我都会得到 zipfile.BadZipFile: Bad CRC-32'

为了测试它,我创建了 p.zip,密码为 p,只有一个文件名为 p.txt 和 运行 此代码:

from zipfile import ZipFile

with ZipFile("p.zip") as zf:
    password = "E"
    try:
        zf.extractall(pwd=bytes(password, "utf-8"))
    except RuntimeError:
        print("wrong password: " + password)

我刚得到 wrong password: E,这是我所期望的。

然而,当我 运行 除了 password = "D" 完全相同的代码时,我得到 zipfile.BadZipFile: Bad CRC-32 for file 'p.txt'

我尝试了几个字符串,例如 pletmeinpassword1DDDDD,它们都可以正常工作。仅设置 password = "D" 给出 zipfile.BadZipFile: Bad CRC-32 for file 'p.txt'.

有人知道这个原因或可能的修复方法吗?

这是控制台上的完整错误:

Traceback (most recent call last):
  File "C:/Users/argolis/workspace/zip-breaker/zip-breaker/script2.py", line 6, in <module>
    zf.extractall(pwd=bytes(password, "utf-8"))
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1594, in extractall
    self._extract_member(zipinfo, path, pwd)
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1649, in _extract_member
    shutil.copyfileobj(source, target)
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 79, in copyfileobj
    buf = fsrc.read(length)
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 876, in read
    data = self._read1(n)
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 966, in _read1
    self._update_crc(data)
  File "C:\Users\argolis\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 894, in _update_crc
    raise BadZipFile("Bad CRC-32 for file %r" % self.name)
zipfile.BadZipFile: Bad CRC-32 for file 'p.txt'

这是解压缩协议的预期行为。有时无效的密码会通过密码校验并被 CRC 校验捕获。来自 man unzip(Linux 文档,但算法与平台无关):

The correct password will always check out against the header, but there is a 1-in-256 chance that an incorrect password will as well. (This is a security feature of the PKWARE zipfile format; it helps prevent brute-force attacks that might otherwise gain a large speed advantage by testing only the header.) In the case that an incorrect password is given but it passes the header test anyway, either an incorrect CRC will be generated for the extracted data or else unzip will fail during the extraction because the ``decrypted'' bytes do not constitute a valid compressed data stream.

有一个 Python bug report 讨论了这个问题。