bkcrack:用 Biham-Kocher 已知明文攻击破解传统 Zip 加密的完整实战指南 网络安全密码学渗透测试【免费下载链接】bkcrackCrack legacy zip encryption with Biham and Kochers known plaintext attack.项目地址https://gitcode.com/gh_mirrors/bk/bkcrack点击查看免费下载本文基于 bkcrack 项目仓库中的 readme.md 展开系统讲解 bkcrack 这一命令行工具的三大核心能力从密文与明文中恢复 ZipCrypto 加密的内部密钥状态、利用内部密钥去除或更换 ZIP 压缩包密码、以及从内部密钥反推原始密码。结合仓库中的源码src/main.cpp、include/Attack.hpp、src/Zreduction.cpp 等与官方示例example/tutorial.md你将掌握从列出压缩包条目到完整恢复出密码的全套操作流程。背景ZipCrypto 为什么能被已知明文攻击攻破一个 ZIP 归档可以包含多个条目entry每个条目可以经过压缩、加密。其中一类使用基于口令的对称加密算法业界称为traditional PKWARE encryption传统 PKWARE 加密也叫 legacy encryption 或ZipCrypto。这类加密的工作方式是加密器维护一个由三个 32 位整数构成的内部状态即X、Y、Z三个密钥分量状态先用口令初始化然后在加密过程中随着明文不断向前推进update生成器输出一个伪随机字节流keystream密钥流密钥流与条目内容明文做XOR得到密文。在 bkcrack 的源码中这一状态由 include/Keys.hpp 定义三个分量的初始值为经典的0x12345678、0x23456789、0x34567890状态推进逻辑见 include/Keys.hpp 中的update()方法void update(std::uint8_t p) { x Crc32Tab::crc32(x, p); y (y lsb(x)) * MultTab::mult 1; z Crc32Tab::crc32(z, msb(y)); }这种结构被 Eli Biham 和 Paul C. Kocher 在论文《A known plaintext attack on the PKZIP stream cipher》中证明存在已知明文攻击known plaintext attack只要拿到密文以及与之对应的12 字节或更多的已知明文就可以恢复出密钥流生成器的内部状态。恢复出内部状态后可以完整解密被攻击条目的全部密文还可以解密归档中所有用同一口令加密的其他条目也可以用来暴力搜索口令其复杂度为nl-6n是字符集大小l是口令长度——因为攻击已经消耗掉了 6 个字节的信息量。bkcrack就是实现这一攻击的命令行工具。如 readme.md 所述它的主功能有三条从密文和明文中恢复内部状态recover internal state利用内部状态去除或更改 ZIP 归档的口令remove or change a ZIP archives password从内部状态反推原始口令recover the original password。安装 bkcrack预编译包最新的官方发布版本提供针对Ubuntu、macOS 和 Windows的预编译包下载后解压到任意目录即可使用。Windows 上运行需要 Microsoft 运行时库如果系统未安装需要下载并安装最新的 Microsoft Visual C Redistributable 包。从源码编译项目使用 CMake。下载源码或克隆仓库后在源码树根目录执行以下命令会在install文件夹中生成一个完整的安装包含可执行文件、example示例、tools脚本和文档cmake -S . -B build -DCMAKE_INSTALL_PREFIXinstall cmake --build build --config Release cmake --build build --config Release --target install构建时默认使用 Release 构建类型CMAKE_BUILD_TYPE未指定时会在 CMakeLists.txt 中自动设为Release。当前仓库对应的版本号为1.7.1CMakeLists.txt。第三方仓库bkcrack 也被收录在多个发行版的软件包仓库中这些包由外部维护者提供。如果你的发行版如 Arch、Debian/Ubuntu 等社区仓库中有bkcrack包也可以直接通过包管理器安装。快速上手列出归档条目在攻击之前先用-L--list查看归档中每个条目的元数据bkcrack -L archive.zip输出会列出每个条目的索引、加密方式ZipCrypto/None/Other、压缩方式、CRC32、未压缩大小、压缩后大小与文件名。这部分逻辑实现在 src/main.cpp 的listEntries()函数中。只有使用ZipCrypto 加密的条目才能遭受已知明文攻击-L的输出正是判断目标是否可行的第一步。仓库自带的 example/secrets.zip 就是一个可动手练习的目标-L输出为该输出同时是 tests/CMakeLists.txt 中cli.list测试的断言内容Archive: secrets.zip Index Encryption Compression CRC32 Uncompressed Packed size Name ----- ---------- ----------- -------- ------------ ------------ ---------------- 0 ZipCrypto Deflate 7ca9f10a 54799 54700 advice.jpg 1 ZipCrypto Store a99f1d0d 1265 1277 spiral.svg可以看到advice.jpg使用 Deflate 压缩而spiral.svg是未压缩存储的Store——后者对攻击者来说是最理想的已知明文来源。恢复内部密钥Recover internal keys攻击对已知明文的要求源码中定义于 include/Attack.hpp要求数值源码常量连续已知明文至少8 字节Attack::contiguousSize已知明文总量至少12 字节Attack::attackSize加密头长度12 字节Data::encryptionHeaderSize已知明文越长尤其是连续部分攻击越快。从 ZIP 归档加载数据假设有加密归档encrypted.zip其中条目cipher是密文另有明文归档plain.zip其中条目plain是已知明文bkcrack -C encrypted.zip -c cipher -P plain.zip -p plain各参数含义完整解析逻辑见 src/Arguments.cpp-C, --cipher-zip archive包含密文条目的 ZIP 归档-c, --cipher-file entry归档中密文条目的名称也可用--cipher-index index按索引指定-P, --plain-zip archive包含明文条目的 ZIP 归档-p, --plain-file entry归档中明文明文条目的名称也可用--plain-index index。一个值得注意的实现细节当密文从 ZIP 归档加载时bkcrack 会自动把该条目的 check byte校验字节加入已知明文。按照 ZIP 格式规范每个条目数据在加密前会先拼接一个 12 字节的加密头encryption header该头以前 11 个随机字节开始、最后 1 个字节可由条目元数据CRC32 或文件大小推断。这一“免费”的已知字节在 src/Arguments.cpp 中实现if (!ignoreCheckByte !extraPlaintext.count(-1)) { extraPlaintextWithCheckByte extraPlaintext; (*extraPlaintextWithCheckByte)[-1] entry.checkByte; }也就是说从归档读取密文时你实际多 1 字节已知明文对应偏移 -1即加密头内的最后一字节。若不需要它可用--ignore-check-byte关闭。从普通文件加载数据如果密文已经单独导出为文件cipherfile注意文件开头必须包含 12 字节加密头明文为plainfilebkcrack -c cipherfile -p plainfile从文件读取密文时不会自动附加 check byte只有当你自己把加密头对应的明文字节也放进明文文件才行。指定偏移-o, --offset如果已知明文对应的是密文中段而非开头需要指定偏移bkcrack -c cipherfile -p plainfile -o offset偏移是相对于“不含加密头”的密文而言的如果明文覆盖了加密头的一部分偏移可以为负数最小值是-12即整个加密头这一约束在 src/Arguments.cpp 和 src/Data.cpp 中都有校验。稀疏明文-x, --extra有时你只有 811 字节的连续明文不够 12 字节总量。此时可以再用-x在其它已知偏移处补充零散字节凑齐 12 字节总量。-x接受“偏移 十六进制字节串”可重复使用bkcrack -c cipherfile -p plainfile -x 25 4b4f -x 30 21上例中偏移 25 处补充 2 字节4b 4f偏移 30 处补充 1 字节21。实现上src/Data.cpp 的构造函数会对这些零散字节做优化与连续明文相邻的字节会被合并如果某段零散字节比原有连续明文更长会自动切换为以最长连续段作为基准从而让攻击速度最优src/Data.cpp。攻击的内部流程运行bkcrack -C ... -c ... -p ...之后src/main.cpp 中的调用链大致是args.loadData()按上面说明的方式加载密文与明文构造Data结构计算密钥流密文 XOR 明文见 src/Data.cppZreduction先用密钥流最后一字节把 2^30 个可能的 Z 状态缩减为 2^22 个候选构造器遍历 122如果已知明文超过 8 字节连续段再用多余字节逐位向前缩减寻找候选数量最小的位置src/Zreduction.cpp 构造、src/Zreduction.cpp 的reduce()Zreduction::generate()把缩减后的候选扩展成完整 32 位 Z 候选值attack()对每个 Z 候选做 meet-in-the-middle 式的 Z 列表/Y 列表/X 列表验证include/Attack.hpp多线程并行默认线程数为 CPU 硬件并发数可用-j调整见 src/Arguments.cpp找到能完全还原 X、Y、Z 三元组的解。典型输出如下取自 example/tutorial.md 的实跑记录[17:42:43] Z reduction using 13 bytes of known plaintext 100.0 % (13 / 13) [17:42:44] Attack on 542303 Z values at index 6 Keys: c4490e28 b414a23d 91404b31 33.9 % (183750 / 542303) Found a solution. Stopping. You may resume the attack with the option: --continue-attack 183750 [17:48:03] Keys c4490e28 b414a23d 91404b31三个十六进制数就是内部密钥 X、Y、Z。如果攻击被中断例如按 CtrlC或未穷尽所有候选就提前停止会打印断点提示可用--continue-attack checkpoint从中断处继续。若希望找到全部可能的密钥而不止第一个解加-e, --exhaustive。解密数据Decipher成功攻击后可以直接把被攻击条目对应的解密数据deciphered data写到文件bkcrack -c cipherfile -p plainfile -d decipheredfile也可以在后续命令中直接用已知密钥省去重新攻击bkcrack -c cipherfile -k 12345678 23456789 34567890 -d decipheredfile-k, --keys X Y Z接受三个 32 位整数的十六进制表示且必须搭配-d、-D、-U、--change-keys或--bruteforce之一使用参数校验见 src/Arguments.cpp。写出的解密数据默认丢弃 12 字节加密头若希望保留头部加--keep-header。注意-d输出的是解密后但未解压的数据——它是否还需要解压取决于打包时该条目是否用了压缩。bkcrack 在 src/main.cpp 中会顺便提示该条目的压缩方式not compressed或compressed with ... method。用 Python 脚本解压 deflate 数据如果条目使用了 deflate 压缩仓库tools目录提供了现成的 Python 3 脚本 tools/inflate.py内部使用zlib.decompress(data, -zlib.MAX_WBITS)处理裸 deflate 流python3 tools/inflate.py decipheredfile decompressedfile对应地tools目录还有 tools/deflate.py 做反向压缩可用于测试场景。去除密码Remove password如果想一步拿到加密归档中所有条目可以基于原归档生成一个内容相同但不带加密的新归档bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -D decrypted.zip该命令假设归档中所有条目原本都使用同一口令加密ZipCrypto 归档通常如此。实现上是Zip::decrypt()逐条解密写出src/main.cpp完成后任何标准 zip 工具都能直接解压生成的新归档。更换密码Change password也可以生成一个新加密归档使用你自己选择的口令bkcrack -C encrypted.zip -k 12345678 23456789 34567890 -U unlocked.zip new_password更底层一点还可以直接指定新归档的“内部密钥表示”而非口令文本适用于你只知道等价密钥、不知道口令原文的场景bkcrack -C encrypted.zip -k 12345678 23456789 34567890 --change-keys unlocked.zip 581da44e 8e40167f 50c009a0这两条命令组合起来还有一个高级玩法readme.md 原文推荐的工作流在完全不知道原口令、只知道内部密钥的情况下修改归档内容——用-U把归档复制成一份用你自选口令加密的副本用任意归档管理器打开副本、输入自选口令编辑内容再用--change-keys把修改后的副本换回原来的内部密钥。恢复原始口令Recover password有了内部密钥还可以尝试找回原始口令本身。做法是在给定字符集上枚举口令候选逐个推导其内部表示并与已知密钥比对。核心选项-b, --bruteforce charset字符集-l, --length min..max口令长度区间也支持min..、..max、或精确长度-r, --recover-password length charset上面两者的快捷形式--recover-password N charset等价于长度区间0..N。字符集可以写任意字面字符也可以用?引导的预定义缩写定义见 src/main.cpp 的 usage 与 src/Arguments.cpp 的readCharset()缩写含义等价字符?l小写字母a-z?u大写字母A-Z?d十进制数字0-9?s特殊字符!#$%()*,-./:;?[\]^_\{}~?a字母数字同?l?u?d?p可打印 ASCII同?l?u?d?s空格到~?b全部字节0x00-0xff例如在字符集?p可打印 ASCII上搜索长度不超过 10 的口令bkcrack -k 1ded830c 24454157 7213b8c5 -r 10 ?p或者显式指定一个长度区间最小 11、最大 13bkcrack -k 18f285c6 881f2169 b35d661d -r 11..13 ?p由于搜索空间是nl-6n为字符集大小l为口令长度长度与字符集的选择决定成败字符集太小会漏掉真实口令太大则时间不可接受。实践中通常按“先小长度全字节扫描、再加大长度限定字符集”的方式分层尝试。若搜索被中断可用--continue-recovery checkpoint十六进制字符串从断点继续。tests/CMakeLists.txt 中的一组cli.bruteforce.*测试覆盖了从空口令-r 0 ?b到 12 位小写口令-r 12 ?l的各种恢复场景。完整示例攻击 secrets.zip仓库 example/tutorial.md 提供了端到端教程配合 example/secrets.zip 使用。流程回顾查看归档bkcrack -L secrets.zip发现spiral.svg未压缩存储advice.jpg使用 Deflate。猜测明文spiral.svg很可能是以?xml version1.0开头的 SVG/XML 文件——20 字节已知明文加上自动附加的 check byte实际已知 21 字节echo -n ?xml version1.0 plain.txt攻击恢复密钥bkcrack -C secrets.zip -c spiral.svg -p plain.txt得到密钥c4490e28 b414a23d 91404b31。这一步的输入输出与 tests/CMakeLists.txt 中cli.attack测试断言的完全一致该测试甚至演示了用-x提供全部已知字节并--continue-attack 183500续跑的情形。去除密码bkcrack -C secrets.zip -k c4490e28 b414a23d 91404b31 -D secrets_without_password.zip或者换一个新密码示例用easybkcrack -C secrets.zip -k c4490e28 b414a23d 91404b31 -U secrets_with_new_password.zip easy或者逐条解密未压缩条目解密即可用Deflate 条目还要过一遍 tools/inflate.pybkcrack -C secrets.zip -c advice.jpg -k c4490e28 b414a23d 91404b31 -d advice_deciphered.deflate python3 tools/inflate.py advice_deciphered.deflate very_good_advice.jpg恢复原始口令先用?b扫长度 0..9 未果再?p扫 10..11 未果最后假设 12 位字母数字bkcrack -k c4490e28 b414a23d 91404b31 --bruteforce ?a --length 12成功恢复出口令W4sF0rgottentests/CMakeLists.txt 的cli.password测试还验证了用--password W4sF0rgotten可以正向推导出同样的密钥。常用命令行参数速查下表汇总 src/main.cpp 中 usage 定义、且与上文各节对应的常用选项完整说明以bkcrack -h为准选项作用-C, --cipher-zip archive包含密文条目的 ZIP 归档-c, --cipher-file file密文条目名或磁盘上的密文文件--cipher-index index按索引指定密文条目-P, --plain-zip archive包含明文条目的 ZIP 归档-p, --plain-file file明文字符条目名或磁盘上的明文文件--plain-index index按索引指定明文条目-t, --truncate size最多加载的明文字节数默认 1 MiBinclude/Arguments.hpp-o, --offset offset明文相对无头密文的偏移可为负最小 -12-x, --extra offset data在指定偏移补充十六进制明文可重复--ignore-check-byte不自动使用条目 check byte 作为已知明文--continue-attack checkpoint从中断/未穷尽处继续攻击--password password由口令正向推导内部密钥测试/撤销--change-keys等场景-k, --keys X Y Z直接提供内部密钥须配合-d/-D/-U/--change-keys/--bruteforce-d, --decipher file写出被攻击条目的解密数据--keep-header解密数据中保留 12 字节加密头-D, --decrypt archive生成去除密码的归档副本需-C-U, --change-password archive password生成换口令的加密归档副本需-C--change-keys archive X Y Z生成换内部密钥的加密归档副本需-C-b, --bruteforce charset按字符集枚举恢复口令-l, --length range口令候选长度区间/精确长度需--bruteforce-r, --recover-password range charset--length--bruteforce的快捷方式--continue-recovery checkpoint从中断处继续口令恢复-j, --jobs count并行线程数默认取 CPU 硬件并发数-e, --exhaustive穷尽搜索所有解而非找到第一个即停-L, --list archive列出 ZIP 归档条目并退出--version/-h版本信息 / 帮助适用范围与注意事项仅针对 ZipCryptotraditional PKWARE encryption从源码结构看Zip::checkEncryption(entry, Zip::Encryption::Traditional)的调用如 src/Arguments.cpp表明攻击路径只对传统加密条目生效-L输出中的Other加密方式不在支持范围内。明文来源决定可行性最可靠的已知明文是未压缩Store条目的文件头如 XML、图片、PE/ELF 文件魔数等对 deflate 条目只有当原始文件容易获得并能复现出相同的压缩字节流时才现实example/tutorial.md 中专门讨论了这一点。数据量与内存-t默认只加载 1 MiB 明文源码注释指出加载更多明文会多用内存但并不能明显加快攻击include/Arguments.hpp。口令恢复的复杂度nsupl-6/sup意味着口令越长、字符集越大恢复时间增长越快先用小字符集小长度快速排除再逐步放宽是 example/tutorial.md 推荐的思路。项目的 API 文档可通过 doxygen 生成doc目录doc/index.md构建时以-DBKCRACK_BUILD_DOCON启用已知限制列表也由 doxygen 从源码标记中生成doc/limitations.md。小结bkcrack 将 Biham-Kocher 对 ZipCrypto 的已知明文攻击做成了一个功能完整、参数丰富的命令行工具-L侦察归档-C/-c/-P/-p/-o/-x组织密文明文完成攻击-d/-D/-U/--change-keys消费内部密钥完成数据恢复与口令置换-r从内部密钥反推口令原文。对于使用传统 ZipCrypto 加密的旧式 ZIP 归档只要你能凑齐 12 字节已知明文其中 8 字节连续这条攻击链在仓库提供的example示例与tests自动化测试tests/CMakeLists.txt中都有可复现的验证路径。项目采用 zlib/png license 许可license.txt可自由用于研究与工程场景。赞分享网络安全密码学渗透测试【免费下载链接】bkcrackCrack legacy zip encryption with Biham and Kochers known plaintext attack.项目地址https://gitcode.com/gh_mirrors/bk/bkcrack点击查看免费下载相关推荐bkcrack利用已知明文分析技术恢复传统ZIP加密的强大工具在数据恢复和数字取证领域经常会遇到因密码遗忘而被锁定的ZIP压缩文件。bkcrack正是为解决这一问题而生的专业工具它基于Eli Biham和Paul C.网络安全密码学渗透测试bkcrack 实战教程用已知明文攻击破解 ZipCrypto 加密的 zip 文件bkcrack 实战教程用已知明文攻击破解 ZipCrypto 加密的 zip 文件 本篇基于 example/tutorial.md https://lin网络安全密码学渗透测试忘记ZIP密码怎么办bkcrack已知明文恢复指南当你面对一个重要的ZIP压缩文件却忘记了密码时那种无助感确实令人沮丧。传统ZIP加密虽然保护了你的数据但也可能成为数据恢复的障碍。幸运的是bkcrack这网络安全密码学渗透测试创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考