密码字典生成
本帖最后由 hrh123 于 2023-9-7 23:11 编辑# Python实现密码字典生成
## 引言
这个工具十分简单,实现的功能就是根据字符集和密码长度生成一个密码字典
## 生成
首先,说到这个,我的思路就是传入一个长度的列表和字符集列表,再根据此输出一个密码源的列表.
要实现这个功能,`itertools.combinations`绝对是个不错的方法.
这个函数返回输入的可迭代对象中元素组成要求长度的子序列
很多人用IDE查看定义,却发现在一个pyi文件下,定义也很抽象,这是因为此模块在底层由C语言实现,代码在`Modules/itertoolsmodule.c`下可找到,用Python实现相当于(仅供参考)
```python
def combinations(iterable, r):
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = list(range(r))
yield tuple(pool for i in indices)
while True:
for i in reversed(range(r)):
if indices != i + n - r:
break
else:
return
indices += 1
for j in range(i+1, r):
indices = indices + 1
yield tuple(pool for i in indices)
```
为了保证效率,我们这里直接用这个模块(`from itertools import combinations`)而不是使用以上的Python实现.
总之,我们可以得到一个初步的函数
```python
def gen_word(length: int, charset: list) -> list:
strings = []
strings.extend(combinations(charset, length))
return ["".join(string) for string in strings]
```
这个函数获取了每个长度对应的字符串列表
接着,我们用for循环就可以简单地实现我们想要的功能了
```python
def gen(length: list, charset: list) -> list:
password_list = []
for l in range(1, len(length) + 1):
password = gen_word(l, charset)
password_list.extend(password)
return password_list
```
代码很易懂不解释了
## GUI
写完了核心功能,剩下就能随意自定义了,我这边写了个简单的GUI,仅供参考
```python
import string
import tkinter as tk
import tkinter.filedialog as filedialog
import tkinter.messagebox as messagebox
import tkinter.ttk as ttk
class GUI(ttk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.master = master
self.master.title("密码字典生成器")
self.grid()
self.create_widgets()
def create_widgets(self):
self.cue_label1 = ttk.Label(self, text="起始长度")
self.cue_label1.grid(row=0, column=0)
self.cue_label2 = ttk.Label(self, text="结束长度")
self.cue_label2.grid(row=0, column=1)
self.entry_var1 = tk.StringVar()
self.entry_var2 = tk.StringVar()
self.entry1 = ttk.Entry(self, textvariable=self.entry_var1, justify=tk.CENTER)
self.entry1.grid(row=1, column=0)
self.entry2 = ttk.Entry(self, textvariable=self.entry_var2, justify=tk.CENTER)
self.entry2.grid(row=1, column=1)
self.check_frame = ttk.Frame(self)
self.check_frame.grid(row=2, column=0, rowspan=2)
self.var_upper = tk.BooleanVar()
self.var_lower = tk.BooleanVar()
self.var_digit = tk.BooleanVar()
self.var_punct = tk.BooleanVar()
self.check_upper = ttk.Checkbutton(
self.check_frame, text="大写字母", variable=self.var_upper
)
self.check_upper.grid(row=0, column=0)
self.check_lower = ttk.Checkbutton(
self.check_frame, text="小写字母", variable=self.var_lower
)
self.check_lower.grid(row=0, column=1)
self.check_digit = ttk.Checkbutton(
self.check_frame, text="数字", variable=self.var_digit
)
self.check_digit.grid(row=0, column=2)
self.check_punct = ttk.Checkbutton(
self.check_frame, text="特殊字符", variable=self.var_punct
)
self.check_punct.grid(row=0, column=3)
self.export_frame = ttk.Frame(self)
self.export_frame.grid(row=2, column=1)
self.button_export = ttk.Button(
self.export_frame, text="导出", command=self.export_cmd
)
self.button_export.grid(row=0, column=0)
self.model_var = tk.BooleanVar()
self.model_var.set(True)
self.check_model = ttk.Checkbutton(
self.export_frame, text="追加模式", variable=self.model_var
)
self.check_model.grid(row=0, column=1)
self.c_label = ttk.Label(self, text="Free Software From Www.52PoJie.Cn")
self.c_label.grid(row=3, column=1)
def export_cmd(self):
try:
self.length_small = int(self.entry_var1.get())
self.length_big = int(self.entry_var2.get())
if self.length_small <= 0 or self.length_big <= 0:
messagebox.showwarning("错误", "请输入正整数")
return ""
if self.length_small >= self.length_big:
messagebox.showwarning("错误", "请按照提示输入")
return ""
except ValueError:
messagebox.showerror("错误", "请输入整数")
return ""
self.length = list(range(self.length_small, self.length_big + 1))
allowed_chars = ""
if self.var_upper.get():
allowed_chars += string.ascii_uppercase
if self.var_lower.get():
allowed_chars += string.ascii_lowercase
if self.var_digit.get():
allowed_chars += string.digits
if self.var_punct.get():
allowed_chars += string.punctuation
self.charset = list(allowed_chars)
if not self.charset:
messagebox.showwarning("错误", "请至少选择一个字符集")
return ""
file_name = filedialog.asksaveasfilename(
filetypes=[("文本文档", "*.txt"), ("所有文件", "*.*")]
)
self.result = gen(self.length, self.charset)
try:
self.export_file(self.result, file_name)
except Exception:
messagebox.showerror("错误", "导出失败")
return ""
messagebox.showinfo("成功", "导出成功")
def export_file(self, content, file_name):
if self.model_var.get():
with open(file_name, "a", encoding="utf-8") as f:
for item in content:
f.write("%s\n" % item)
else:
with open(file_name, "w", encoding="utf-8") as f:
for item in content:
f.write("%s\n" % item)
def main():
root = tk.Tk()
gui = GUI(master=root)
gui.master.mainloop()
# main()
```
### GUI说明
此GUI仅提供最基础功能,在面对生成大字典时普遍会造成较长的卡顿,有条件还是自己配置GUI,异步,多进程等. 本帖最后由 hrh123 于 2023-9-10 06:47 编辑
Love0912 发表于 2023-9-9 16:07
我知道你说的这个,我是说如何优化密码字典,来增加撞库的成功率和效率。。。。因为这玩意我也没啥思路, ...
密码分析的内容,这和字典关系不大,也不是暴力搜索这种方式能做的,字典能做的或许是增加社会工程学手段,比如利用常见的弱口令等
首先,先确保你知道对方用的是什么密码系统(克尔克霍夫假设)
其次,你需要根据对应的算法,对症下药
比如,目前大部分的hash函数都有已知的碰撞弱点(包括但不限于MD5,SHA0.SHA1,RIPEMD160,RIPEMD128等),(当然,大部分用于数字签名的hash函数都有抗碰撞性)
再比如.很多加密hash算法(包括但不限于MD5,SHA256/512)都基于Merkle-Damgard结构,都容易受到长度扩展攻击
当然,这些方法并不一定能成功,因为有些密码系统可能采用了更复杂的设计或者更强的防御措施.例如,有些hash函数(如SHA3,Blake2等)是基于Sponge结构的,不受长度扩展攻击的影响,有些密码系统可能使用了salt或nonce来增加hash值的随机性和复杂度,有些可能使用了KDF或KSA来增加破解的时间和成本
总的来说,想要增加撞库的成功率和效率你得根据具体的算法来分析,调整你的破解手段,这不是一个字典生成器能帮你做的
要是通过字典攻击就能简单地破解一个成熟的密码系统,密码学也就不存在了 非常有用,点赞支持 Python语言yyds 虽然在重复造轮子,但还是给楼主的精神点赞 支持原创,感谢分享。 adm1nSQL 发表于 2023-9-7 23:45
虽然在重复造轮子,但还是给楼主的精神点赞
哪里在造轮子?是有啥库能直接实现此功能吗? 看这生成模式来说听中规中矩的,就是大家对密码这东西有啥特殊想法么。因为实现密码生成不麻烦,麻烦的是如何精简密码库,类似于大数据精确定位密码的那种~ 不错,感谢分享 谢谢分享 感谢分享