☰
Hashcat与John the Ripper实战:压缩包密码恢复全链路与CUDA避坑指南
2026/11/3 20:08:11 网站建设 项目流程

密码恢复这件事,外行看热闹,内行看门道。网上流传的教程大多只告诉你敲哪几行命令,却很少讲清楚为什么这么敲、什么情况下根本敲不通、以及跑起来之后机器为什么突然变慢甚至报错。我前后在几台不同配置的机器上折腾过压缩包密码恢复,踩过的坑比跑出来的密码还多。这篇内容就围绕Hashcat和John the Ripper这两款主流工具,讲清楚压缩包密码恢复的完整链路——从哈希提取、模式选择、显卡计算环境配置,到实测中的性能调优和常见报错处理。适合有一定命令行基础、想真正把这件事跑通而不是复制粘贴碰运气的读者。下面所有操作都建议在你自己的、有合法授权的文件上进行,这一点必须先说在前面。

1. 先搞清楚你在恢复什么:压缩包密码的验证机制

很多人一上来就找命令,结果连自己要处理的是哪种加密格式都没确认,跑半天没结果还以为是工具不行。压缩包密码恢复的第一步不是选工具,而是搞清楚目标文件的加密方式,因为这直接决定了后面哈希怎么提取、用哪种攻击模式。

1.1 ZIP的两种加密体系差别巨大

ZIP格式存在两套完全不同的加密方案,这是新手最容易混淆的地方。一套是流传很久的ZipCrypto(也叫传统加密),另一套是AES-256加密(WinZip AES)。两者在密码验证的数学结构上完全不同,恢复难度和工具支持也不一样。

ZipCrypto的验证机制相对薄弱:它用一个12字节的加密头来校验密码,密码错误时校验位对不上就直接判定失败。这个结构的特点是验证速度快,但存在已知的明文攻击弱点(这里不展开,因为那属于另一类技术路线)。对密码恢复来说,ZipCrypto的每次尝试计算量小,所以同样的硬件下每秒尝试次数(也就是常说的hash rate)会高很多。

AES-256则完全不同。它使用PBKDF2-HMAC-SHA1做密钥派生,默认迭代1000次(WinZip的实现),每次密码尝试都要完整跑一遍密钥派生流程。这意味着单次尝试的计算成本比ZipCrypto高出两到三个数量级。你在ZipCrypto上能跑到每秒几百万次尝试的机器,换到AES-256上可能只剩每秒几千次。这个差距必须提前有心理预期,否则很容易误判"工具是不是没跑起来"。

判断方法很简单,用zipinfo或者直接看文件头:

zipinfo -v target.zip | grep -i "encryption"

输出里如果出现AES字样就是AES加密,出现traditional或ZipCrypto就是传统加密。另一个土办法是用7z尝试解压,报错信息里通常会点明加密类型。

1.2 RAR的版本差异同样关键

RAR的情况稍微统一一些,但版本差异依然影响巨大。RAR3(对应WinRAR 4.x及更早)和RAR5(WinRAR 5.x之后)的密钥派生算法不同。RAR3使用SHA-1为基础的派生流程,迭代次数相对可控;RAR5则用了更复杂的PBKDF2变体,迭代次数更高,单次尝试成本更大。

用unrar或者7z l -slt可以看出版本信息。这里有个实操细节:Hashcat对RAR3的支持成熟度高于RAR5,模式编号也不同(RAR3是-m 12500,RAR5是-m 13000)。选错模式会直接报"token encoding"或"signature"相关的错误,而不是给你一个友好的提示。

1.3 为什么必须先提取哈希而不是直接喂压缩包

这是很多人不理解的一步。Hashcat本身不直接读ZIP/RAR文件,它需要的是从文件里抽出来的、能独立验证密码的那段哈希数据。提取出来的哈希通常是一个特定格式的字符串,包含了加密头、校验值、盐值等必要信息。这样做的好处是:哈希文件极小,可以脱离原文件反复使用;而且提取过程本身会校验文件完整性,避免在损坏的文件上白跑。

John the Ripper则相对灵活,部分版本可以直接对压缩包操作(内部调用提取逻辑),但为了统一流程和可控性,我习惯先用专用脚本提取,再分别喂给两个工具。提取工具后面会具体讲。

2. 哈希提取:把压缩包变成工具能吃的格式

提取这一步看似简单,实际上是最容易出问题的地方。提取脚本版本不对、文件路径有空格、压缩包本身有多个加密成员,都会导致提取失败或提取出不完整的哈希。

2.1 ZIP哈希提取的两种脚本选择

针对ZIP,社区里常用的提取脚本有两个来源:一个是zip2john(John自带),另一个是Hashcat官方仓库里的zip2hashcat.py。两者输出的格式不同,分别对应各自工具的输入要求。

zip2john的用法:

zip2john target.zip > zip_hash.txt

输出的是一个以$pkzip2$开头的长字符串,John能直接识别。这个脚本对ZipCrypto和AES都支持,但要注意它默认会尝试提取压缩包内所有加密成员,如果压缩包里有多个文件,输出会包含多段哈希。这时候喂给工具要确认工具是否支持多哈希并行,否则可能只处理了第一段。

Hashcat这边用zip2hashcat.py:

python3 zip2hashcat.py target.zip > zip_hash_hc.txt

输出格式以$zip2$(ZipCrypto)或$zip2$带AES标识开头。这里有个坑:不同版本的脚本对AES的支持程度不一样,老版本可能直接报"unsupported encryption"。遇到这种情况先更新脚本到最新,再确认Python依赖(主要是pycryptodome)装好了。

2.2 RAR哈希提取的版本匹配问题

RAR的提取脚本是rar2john(John自带)或Hashcat仓库的rar2hashcat.py。同样存在版本匹配问题。

rar2john target.rar > rar_hash.txt

RAR3提取出来是$RAR3$*0*...格式,RAR5是$rar5$*...格式。Hashcat对这两种格式的模式编号不同,喂进去之前务必确认哈希前缀和-m参数对得上。我见过有人把RAR5的哈希用-m 12500跑,工具不报错但永远跑不出结果,因为模式根本不匹配,验证逻辑走的是另一套。

提示:提取完成后,先用文本编辑器打开哈希文件看一眼前缀。$pkzip2$、$zip2$、$RAR3$、$rar5$这几个前缀分别对应不同的处理路径,认错前缀是"跑不出结果"的头号原因。

2.3 提取失败的常见原因排查

提取阶段报错,按这个顺序查:

现象可能原因处理方式
脚本报"not a zip file"文件扩展名与实际格式不符用file命令确认真实格式
输出为空压缩包未加密或只有部分成员加密用zipinfo确认加密标志
报"unsupported"加密算法版本过新或脚本过旧更新脚本与依赖库
哈希长度异常短提取被截断,常见于路径含特殊字符把文件移到纯英文短路径重试

路径问题值得单独说一句。Windows下如果文件路径带中文或空格,某些Python脚本读取时会出问题,表现是提取到一半中断或输出乱码。最稳妥的做法是把目标文件复制到一个类似/tmp/work/或C:\work\的纯英文短路径下再操作。

3. 显卡计算环境:CUDA配置为什么总在这卡住

密码恢复的性能几乎完全取决于显卡。CPU跑和GPU跑,速度差距可能是几十倍到上百倍。而GPU要发挥作用,计算环境必须配对——这就是标题里说的"CUDA配置避坑"的核心。

3.1 驱动、运行时、工具链三者的版本关系

很多人以为装个显卡驱动就完事了,实际上Hashcat依赖的是CUDA运行时(runtime),而运行时又对驱动版本有最低要求。三者关系是:驱动版本 ≥ 运行时要求的最低驱动 ≥ 工具编译时依赖的运行时版本。任何一环不满足,表现都是Hashcat启动时报No devices found或者clGetPlatformIDs相关错误。

正确的检查顺序:

  1. 先看驱动版本:nvidia-smi,右上角显示Driver Version。
  2. 再看CUDA运行时版本:nvcc --version或nvidia-smi里显示的CUDA Version(注意这个显示的是驱动支持的最高运行时版本,不一定是你装的)。
  3. 最后确认Hashcat识别到的设备:hashcat -I。

hashcat -I的输出会列出所有可用计算设备及其类型(GPU/CPU)。如果这里只看到CPU没看到GPU,说明CUDA运行时没被正确加载,问题一定在环境配置而不是Hashcat本身。

3.2 一个典型的版本错配场景

我遇到过最典型的情况:驱动是比较新的版本,但系统里装的CUDA运行时是旧版,Hashcat编译时链接的是新版运行时。结果就是hashcat -I能看到GPU,但一跑就报cuInit失败或者直接崩溃。

排查思路是看Hashcat启动时的详细日志:

hashcat -I --backend-ignore-cuda hashcat -I --backend-ignore-opencl

分别禁用CUDA和OpenCL后端,看哪个后端能正常列出设备。如果禁用CUDA后OpenCL能列出GPU,说明CUDA运行时确实有问题,而OpenCL路径是通的。这时候有两个选择:修CUDA环境,或者干脆用OpenCL后端跑(性能可能略低但能用)。

修CUDA环境的稳妥做法是:卸载现有运行时,装一个与驱动版本匹配的运行时,装完重启,再用hashcat -I验证。不要试图在旧运行时上"打补丁",版本错配的坑补不完。

3.3 多显卡与显存不足的处理

多显卡机器上,Hashcat默认会用所有GPU。如果某张卡显存较小,跑大字典或复杂规则时可能报显存不足(Out of memory或Memory allocation error)。这时候用-d参数指定设备编号:

hashcat -I # 记下目标GPU的编号,比如1 hashcat -m 13000 -a 0 hash.txt wordlist.txt -d 1

显存不足还有一个隐蔽原因:工作负载参数(workload profile)设得太高。-w 3或-w 4会显著增加显存占用换取速度,小显存卡上直接爆掉。默认-w 2在多数场景下是平衡点,先跑默认,稳定后再尝试调高。

注意:调高workload profile带来的速度提升在密码恢复后期(候选空间很大时)才有意义,前期字典攻击阶段收益不明显,反而增加不稳定风险。我的习惯是先用-w 2跑通,确认稳定后再针对具体任务微调。

4. 攻击模式选择:字典、掩码、混合到底怎么选

工具跑起来只是开始,真正决定成败的是攻击模式。选错模式,再强的显卡也是白跑。这一节把三种主流模式的适用场景和参数写法讲透。

4.1 字典攻击:最常用但也最容易被低估

字典攻击(-a 0)是用一个词表逐个尝试。看起来最简单,实际上词表质量决定了一切。网上随便下的"万能字典"往往包含大量重复和无关词条,跑起来又慢命中率又低。

我的做法是分层准备词表:

  • 基础层:常用密码排行(类似rockyou这类公开词表),覆盖最常见的弱密码。
  • 场景层:根据目标可能的习惯定制,比如包含特定年份、常见名字变体、键盘模式(qwerty、1qaz2wsx这类)。
  • 规则层:不直接堆词表,而是用规则引擎对基础词表做变形。

规则引擎是字典攻击的放大器。Hashcat的-r参数加载规则文件,一条基础密码经过规则变形可以生成几十上百个变体(大小写变换、追加数字、替换字符等)。这比单纯堆一个巨大的词表高效得多,因为规则是运行时展开的,不占额外存储。

hashcat -m 13000 -a 0 hash.txt base_wordlist.txt -r rules/best64.rule

best64.rule是Hashcat自带的经典规则集,64条规则覆盖了最常见的变形模式,作为起点很合适。跑完没结果再换更大的规则集,比如dive.rule(约十万条规则),但要注意规则越多,等效候选空间越大,耗时成倍增长。

4.2 掩码攻击:知道密码结构时的利器

掩码攻击(-a 3)适合你已经对密码结构有判断的场景,比如"8位纯数字"、"首字母大写加6位小写加2位数字"这种。掩码用占位符描述结构:

  • ?d数字 0-9
  • ?l小写字母
  • ?u大写字母
  • ?s特殊符号
  • ?a全部可打印字符

一个8位纯数字密码的掩码就是?d?d?d?d?d?d?d?d,候选空间10的8次方,一亿个。这个量级在像样的显卡上几分钟到几十分钟能跑完(取决于加密类型)。

掩码的威力在于精准。如果你确定密码是"某单词+4位数字",用混合模式(-a 6或-a 7)比纯掩码更高效:

# -a 6: 字典在前,掩码在后 hashcat -m 13000 -a 6 hash.txt wordlist.txt ?d?d?d?d # -a 7: 掩码在前,字典在后 hashcat -m 13000 -a 7 hash.txt ?d?d?d?d wordlist.txt

这里有个计算上的细节值得说清楚。假设词表有10万条,追加4位数字,等效候选空间是10万 × 1万 = 10亿。这个量级在AES-256加密上可能要跑很久,所以混合模式一定要配合对密码结构的合理判断,不能盲目上。

4.3 模式选择的决策逻辑

把选择逻辑整理成一张表更直观:

已知信息推荐模式理由
完全不知道字典 + 规则(-a 0 -r)覆盖面广,先碰运气
知道是纯数字/纯字母掩码(-a 3)精准,空间可控
知道是单词+数字组合混合(-a 6/7)利用结构信息
有部分已知片段掩码中嵌入固定字符进一步缩小空间
字典跑完无果换更大规则集或组合攻击逐步扩大搜索

实际项目中,这几种模式往往是串联使用的:先字典加规则快速筛一遍,没结果再根据目标特征上掩码或混合。不要指望一种模式解决所有问题。

5. John the Ripper的差异化用法

Hashcat在GPU加速上优势明显,但John the Ripper在某些场景下更顺手,尤其是它的"自动检测"能力和对多种格式的统一处理。两者配合使用能覆盖更多情况。

5.1 John的自动格式识别与增量模式

John最大的便利是自动识别哈希格式,不需要手动指定模式编号。把提取好的哈希文件直接喂进去:

john --wordlist=wordlist.txt zip_hash.txt

John会自己判断这是ZIP还是RAR、是哪种加密。这个特性在你不确定哈希格式时特别有用——先用John跑一下看它识别成什么,再决定要不要转到Hashcat上加速。

John的增量模式(incremental)是它的特色功能,本质是一种基于统计的智能掩码,会按字符出现频率排序尝试:

john --incremental zip_hash.txt

这个模式适合完全不知道密码结构、但密码本身不太长的情况。它的候选顺序经过优化,短密码命中率不错,但长密码上不如精准掩码高效。

5.2 John的GPU支持与编译注意事项

John的GPU支持需要专门编译(--enable-opencl或--enable-cuda),发行版自带的二进制往往只编译了CPU版本。这意味着你从包管理器装的John可能根本用不上显卡,跑起来慢得让人怀疑人生。

验证方法:跑John时看它启动信息里有没有列出OpenCL/CUDA设备。没有的话就是CPU版本。要GPU加速得自己从源码编译,编译时确保计算环境已配好(和Hashcat那节的要求一致)。

我的实际取舍是:短字典快速验证用John(省去指定模式的麻烦),大规模跑用Hashcat(GPU利用更充分、参数更细)。两者不是替代关系,是互补关系。

5.3 恢复会话与进度管理

密码恢复可能跑很久,中途中断是常事。两个工具都支持会话恢复,但用法不同。

Hashcat用--session指定会话名,中断后用--restore恢复:

hashcat -m 13000 -a 0 hash.txt wordlist.txt --session myjob # 中断后 hashcat --restore --session myjob

John则用--session配合--restore,但它默认会自动保存进度到~/.john/目录下:

john --session=myjob --wordlist=wordlist.txt zip_hash.txt # 恢复 john --restore=myjob

提示:Hashcat的恢复依赖.restore文件,这个文件默认写在当前工作目录。如果你在不同目录下启动恢复,会找不到进度。养成习惯:跑长任务时固定在一个目录下操作,或者用--restore-file-path显式指定路径。

6. 实测中的性能调优与踩坑记录

前面讲的都是"应该怎么做",这一节讲"实际做的时候会遇到什么"。这些经验大多来自反复试错,文档里不会写。

6.1 温度墙与降频:跑得快不如跑得稳

GPU长时间满载,温度上去之后会触发降频保护,hash rate断崖式下跌。我见过一张卡刚开始跑每秒几十万次,十分钟后掉到几万次,就是因为散热跟不上。

监控温度用nvidia-smi -l 1(每秒刷新)。如果温度持续逼近显卡的温度上限(不同卡不同,通常在80-90度区间),要么改善散热,要么用--hwmon-temp-abort设置一个温度阈值让Hashcat自动暂停:

hashcat -m 13000 -a 0 hash.txt wordlist.txt --hwmon-temp-abort=85

这个参数的意思是温度到85度就中止,保护硬件。跑长任务时建议加上,宁可慢一点也别把卡跑坏。

6.2 字典顺序对命中时间的影响

字典攻击是按词表顺序逐个尝试的。如果高频密码排在词表后面,就要等很久才轮到。所以词表内部的排序很重要——把最可能的密码放前面。

实操上,我会把词表按"可能性"分层拼接:先放针对目标定制的少量高概率候选,再放通用高频密码,最后放全量词表。这样即使全量部分要跑很久,前面的高概率部分几分钟内就能出结果(如果命中)。

6.3 一个容易被忽略的细节:哈希文件里的多段数据

前面提过,一个压缩包里有多个加密成员时,提取出的哈希文件可能包含多段。Hashcat默认只处理第一段(或者说按行处理,但同一文件的多段需要确认格式)。如果密码其实对应的是第二段成员,就会漏掉。

处理办法是先看哈希文件有几行有效数据:

grep -c '^\$' zip_hash.txt

如果大于1,说明有多段。这时候要么分别提取成多个文件逐个跑,要么确认工具是否支持多哈希模式(Hashcat的--username和某些模式支持批量,但压缩包哈希的批量支持要看具体版本)。稳妥起见,我倾向于拆分成单段分别处理,避免遗漏。

6.4 关于"跑不出结果"的系统性排查

跑完没结果,按这个链路查,基本能定位问题:

  1. 哈希提取是否正确:拿一个你知道密码的测试压缩包,用同样流程提取并跑,能跑出来说明流程通。
  2. 模式编号是否匹配:哈希前缀和-m参数是否对应,这是最高频的错误。
  3. 候选空间是否覆盖:密码结构判断是否准确,掩码或规则是否覆盖了真实密码的形态。
  4. 是否真的跑完了:看Hashcat的Status是否为Exhausted,中途中断或报错不算跑完。
  5. 硬件是否稳定:温度、显存、驱动报错都可能导致中途静默失败。

这个排查顺序是从"流程正确性"到"参数正确性"再到"硬件稳定性",逐层排除。我踩过的坑里,前两层占了八成以上。

7. 合法边界与负责任的使用

技术本身中性,但使用场景有边界。压缩包密码恢复的正当用途包括:恢复自己遗忘密码的备份文件、在获得明确授权的前提下对自有资产做安全评估、取证场景下对合法持有的数据做分析。超出这些范围的使用不在本文讨论之列,也不应该尝试。

从防御角度看,理解这套流程反而能帮你做出更好的保护决策。比如:知道ZipCrypto的验证机制薄弱、单次尝试成本低,就应该避免用它保护敏感数据,改用AES-256;知道密码长度和字符集直接决定候选空间大小,就应该在密码强度上留足余量——一个12位以上、混合大小写数字符号的密码,其候选空间足以让任何硬件在可接受时间内放弃。这些判断比单纯记几条命令有价值得多。

我在实际配置环境时最大的体会是:工具跑通只是起点,真正花时间的是环境匹配和参数判断。CUDA版本、驱动版本、哈希格式、攻击模式,这四样任何一样对不上,表现都是"跑不出结果"这种没有明确报错的沉默失败。所以每次开新任务前,我都会先用一个已知密码的小文件做端到端验证,确认整条链路通了再上真实目标。这个习惯帮我省下的时间,远比多背几个参数多得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询