python暴力解压rar加密文件过程详解


Posted in Python onJuly 05, 2019

第一次使用csdn写文章,写得不好还请见谅。(运行环境:python3.6)

下了一个带密码的压缩包文件,作为一个刚学python的新手,想着能不能用python暴力破解它,于是在网上搜了很多资料,看着似乎并不是很麻烦,也想试着自己写一个可以暴力破解的程序,在写的过程中却遇到了各种各样的问题,希望大手们能带带我。遇到的问题如下:

  • zipfile和zipfile2似乎都不支持AES解密(https://bugs.python.org/issue9170)
  • 在用rarfile暴力破解时即使密码错误也不抛出异常,因此无法用try,except捕获密码

本来是想写一个可以同时暴力破解zip和rar的程序,在试了半天解密zip却一直提示密码错误之后放弃了zip,想着能不能写一个暴力破解rar的程序。

首先是生成字典:要用到itertools模块

import itertools as its
import string

def createDict(path,repeats,words):
	dict = its.product(words,repeat=repeats) 
	'''这里的words是要迭代的字符串,repeats是生成的密码长度,生成的dict是一个返回元组的迭代器'''
	f = open(path,'a')
	for cipher in dict:
		f.write(''.join(cipher) + '\n')
	f.close()

def main():
	numbers = string.digits #包含0-9的字符串
	path = '输入你的字典路径'
	length = 你要迭代的密码长度
	for i in range(1,length):
		createDict(path,i,numbers)

if __name__=="__main__":
	main()

到这里我们的字典已经生成完毕了,接下来开始暴力破解rar

from threading import Thread
from unrar import rarfile
import os

'''首先我们要读取字典,字典可能太大因此我们采用迭代器'''

def get_pwd(dict_path):
	with open(dict_path,'r') as f:
		for pwd in f:
			yield pwd.strip()

def decode_rar(fp,pwd,extract_path):
	try:
		fp.extractall(extract_path,pwd=pwd) 
	except:
		pass
	else:
		print('the pwd is>',pwd)
'''
事实上我在尝试时似乎从来没有到达过else,这样可能是得不到解压密码的。我的
一种得到密码的想法如下,但是运行效率可能会降低


def decode_rar(fp,pwd,check_file,extract_path):
	fp.extractall(extract_path,pwd=pwd)
	if os.path.exists(check_file):
		print('The pwd is:',pwd)
		exit(0)
其中check_file可以设置为fp.namelist()[0]
并且该方法不能使用多线程,因此速度会降低很多
'''

def main():
	extract_path = '你要解压的路径'
	dict_path = '你的字典路径'
	filename = '你的rar路径'
	fp = rarfile.RarFile(filename)
	pwds = get_pwd(dict)
	'''使用多线程可提高速度'''
	for pwd in pwds:
		t = Thread(target=rar_file,args=(fp,pwd,extract_path))
		t.start()

以上是写程序的思路和遇到的各种坑,代码是手敲的,可能有一些错误,希望能得到谅解和帮助。

下面是一个图形界面的rar解密源代码:(图形只是想练习,运行较慢,建议直接运行上面的函数)

import tkinter as tk
import os
from tkinter import messagebox
from unrar import rarfile
from threading import Thread

def getPwd(dict):
  with open(dict,'r') as f:
    for pwd in f:
      yield pwd.strip()
def slowerDecode(fp,pwd,check_file,extract_path):
  fp.extractall(extract_path,pwd=pwd)
  if os.path.exists(check_file):
    messagebox.showinfo(message="密码:"+pwd)
    messagebox.showinfo(message="程序结束")
    messagebox.showinfo(message="密码:"+pwd)
    exit(0)
	
def quickDecode(fp,pwd,extract_path):
  fp.extractall(extract_path,pwd=pwd)


def check(obs):
  flag = 1
  for ob in obs:
    if not ob.checkExist():
      flag = 0
      ob.showError()  

  if(not flag):
    return 0
  else:
    for ob in obs:
      if not ob.check():
        flag = 0
        ob.showError()
		
  if (not flag):
    return 0
  else:
    for ob in obs:
      ob.right()
    return 1
		
def main(obs):
  extract_path = obs[0].path_input.get()
  rar_path = obs[1].path_input.get()
  txt_path = obs[2].path_input.get()
  pwds = getPwd(txt_path)
  global var1
  global var2
  if(check(obs)):
    if(var1.get() == 0 and var2.get() == 0):
      messagebox.showerror(message="选择一个选项!!!")
    elif(var1.get() == 0 and var2.get() == 1):
      fp = rarfile.RarFile(rar_path)
      check_file = fp.namelist()[0]
      for pwd in pwds:
        slowerDecode(fp,pwd,check_file,extract_path)
    elif(var1.get() == 1 and var2.get() == 0):
      fp = rarfile.RarFile(rar_path)
      for pwd in pwds:
        t = Thread(target=quickDecode,args=(fp,pwd,extract_path))
        t.start()
      exit(0)
    else:
      messagebox.showerror(message="只选择一个!!!")
    

class FolderPath:
  
  def __init__(self,y=0,error_message="Not exists!",path_input="",text=''):
    self.y = y
    self.error_message = error_message
    self.path_input = path_input
    self.text = text
	
  def createLabel(self):
    label = tk.Label(window,bg="white",font=("楷体",13),width=20,text=self.text)
    cv.create_window(100,self.y,window=label)
  
  def createEntry(self):
  	entry = tk.Entry(window,fg="blue",width="40",bg="#ffe1ff",textvariable=self.path_input)
  	cv.create_window(330,self.y,window=entry)
  
  def show(self):
    self.createLabel()
    self.createEntry()
	
  def showError(self,color="red"):
    label = tk.Label(window,bg="white",fg=color,font=("楷体",13),width="10",text=self.error_message)
    cv.create_window(530,self.y,window=label)
  
  def checkExist(self):
    self.error_message = 'Not exists!'
    if not os.path.exists(self.path_input.get()):
      return 0
    return 1
  
  def check(self):
    if not os.path.isdir(self.path_input.get()):
      self.error_message = 'Not a dir!'
      return 0
    else:
      return 1
  
  def right(self):
    self.error_message = "right path!"
    self.showError('#00FFFF')
	
  
class FilePath(FolderPath):
  def check(self):
    if (self.path_input.get().split('.')[-1] == self.suffix):
      return 1
    else:
      self.error_message = "Not "+self.suffix + '!'
      return 0
  

window = tk.Tk()
window.title('made by qiufeng')
window.geometry('600x300')
cv = tk.Canvas(window,width=600,height=300,bg='white')
cv.pack()

folderpath = FolderPath(y=140,path_input=tk.StringVar(),text="请输入解压路径")
folderpath.show()


rarpath = FilePath(y=60,path_input=tk.StringVar(),text="请输入rar路径")
rarpath.suffix = 'rar'
rarpath.show()

txtpath = FilePath(y=100,path_input=tk.StringVar(),text="请输入字典路径")
txtpath.suffix = 'txt'
txtpath.show()
obs = [folderpath,rarpath,txtpath]

#多选框
var1 = tk.IntVar()
var2 = tk.IntVar()
ck1 = tk.Checkbutton(window,text="直接破解(无法获得密码)",variable=var1)
cv.create_window(150,200,window=ck1)
ck2 = tk.Checkbutton(window,text="慢速(可获得密码)",variable=var2)
cv.create_window(132,230,window=ck2)
button = tk.Button(window,text="确认",command=lambda: main(obs))
cv.create_window(90,260,window=button)

window.mainloop()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中的urllib模块使用详解
Jul 07 Python
结合Python的SimpleHTTPServer源码来解析socket通信
Jun 27 Python
Python设计模式之中介模式简单示例
Jan 09 Python
python实现自动发送报警监控邮件
Jun 21 Python
python用pandas数据加载、存储与文件格式的实例
Dec 07 Python
python广度优先搜索得到两点间最短路径
Jan 17 Python
Python跳出多重循环的方法示例
Jul 03 Python
Python: tkinter窗口屏幕居中,设置窗口最大,最小尺寸实例
Mar 04 Python
python和php学习哪个更有发展
Jun 17 Python
详解python的变量缓存机制
Jan 24 Python
2021年pycharm的最新安装教程及基本使用图文详解
Apr 03 Python
python3 sqlite3限制条件查询的操作
Apr 07 Python
Python 使用folium绘制leaflet地图的实现方法
Jul 05 #Python
Python 给定的经纬度标注在地图上的实现方法
Jul 05 #Python
python 自动轨迹绘制的实例代码
Jul 05 #Python
python实现ip代理池功能示例
Jul 05 #Python
解决yum对python依赖版本问题
Jul 05 #Python
python写入文件自动换行问题的方法
Jul 05 #Python
Python Numpy计算各类距离的方法
Jul 05 #Python
You might like
谈一谈收音机的高放电路
2021/03/02 无线电
PHP的可变变量名的使用方法分享
2012/02/05 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
PHP实现的基于单向链表解决约瑟夫环问题示例
2017/09/30 PHP
PHP tp5中使用原生sql查询代码实例
2020/10/28 PHP
关于实现代码语法标亮 dp.SyntaxHighlighter
2007/02/02 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
window.location.reload 刷新使用分析(去对话框)
2015/11/11 Javascript
JavaScrip常见的一些算法总结
2015/12/28 Javascript
深入浅析JSON.parse()、JSON.stringify()和eval()的作用详解
2016/04/03 Javascript
jQuery插件formValidator实现表单验证
2016/05/23 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
Javascript获取随机数的实现方法
2016/06/22 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
2016/11/12 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
解决给dom元素绑定click等事件无效问题的方法
2017/02/17 Javascript
详解Webpack DLL用法以及功能
2017/07/11 Javascript
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
原生JS实现的简单轮播图功能【适合新手】
2018/08/17 Javascript
vue绑定事件后获取绑定事件中的this方法
2018/09/15 Javascript
Vue 实现v-for循环的时候更改 class的样式名称
2020/07/17 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
2020/07/19 Javascript
[02:41]DOTA2英雄基础教程 谜团
2013/12/10 DOTA
[01:06:54]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第二场 2月28日
2021/03/11 DOTA
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
使用Keras预训练模型ResNet50进行图像分类方式
2020/05/23 Python
用纯css3和html制作泡沫对话框实现代码
2013/03/21 HTML / CSS
食品销售计划书
2014/04/26 职场文书
厕所文明标语
2014/06/11 职场文书
优质服务口号
2014/06/11 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书
周一给客户的问候语
2015/11/10 职场文书
《只有一个地球》教学反思
2016/02/16 职场文书
Python 实现Mac 屏幕截图详解
2021/10/05 Python
Python实现灰色关联分析与结果可视化的详细代码
2022/03/25 Python