hrh123 发表于 2023-9-7 23:09

密码字典生成

本帖最后由 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-9 17:34

本帖最后由 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来增加破解的时间和成本
总的来说,想要增加撞库的成功率和效率你得根据具体的算法来分析,调整你的破解手段,这不是一个字典生成器能帮你做的
要是通过字典攻击就能简单地破解一个成熟的密码系统,密码学也就不存在了

daoye9988 发表于 2023-9-7 23:18

非常有用,点赞支持

pianbei 发表于 2023-9-7 23:29

Python语言yyds

adm1nSQL 发表于 2023-9-7 23:45

虽然在重复造轮子,但还是给楼主的精神点赞

netpeng 发表于 2023-9-7 23:49

支持原创,感谢分享。

hrh123 发表于 2023-9-7 23:49

adm1nSQL 发表于 2023-9-7 23:45
虽然在重复造轮子,但还是给楼主的精神点赞

哪里在造轮子?是有啥库能直接实现此功能吗?

Love0912 发表于 2023-9-8 08:33

看这生成模式来说听中规中矩的,就是大家对密码这东西有啥特殊想法么。因为实现密码生成不麻烦,麻烦的是如何精简密码库,类似于大数据精确定位密码的那种~

echoaku 发表于 2023-9-8 09:13

不错,感谢分享

15103802764 发表于 2023-9-8 09:20

谢谢分享

scbzwv 发表于 2023-9-8 09:24

感谢分享
页: [1] 2 3
查看完整版本: 密码字典生成