吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3522|回复: 29
收起左侧

[Python 原创] 密码字典生成

  [复制链接]
hrh123 发表于 2023-9-7 23:09
本帖最后由 hrh123 于 2023-9-7 23:11 编辑

Python实现密码字典生成

引言

这个工具十分简单,实现的功能就是根据字符集和密码长度生成一个密码字典

生成

首先,说到这个,我的思路就是传入一个长度的列表和字符集列表,再根据此输出一个密码源的列表.
要实现这个功能,itertools.combinations绝对是个不错的方法.
这个函数返回输入的可迭代对象中元素组成要求长度的子序列
很多人用IDE查看定义,却发现在一个pyi文件下,定义也很抽象,这是因为此模块在底层由C语言实现,代码在Modules/itertoolsmodule.c下可找到,用Python实现相当于(仅供参考)

def combinations(iterable, r):
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = list(range(r))
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

为了保证效率,我们这里直接用这个模块(from itertools import combinations)而不是使用以上的Python实现.
总之,我们可以得到一个初步的函数

def gen_word(length: int, charset: list) -> list:
    strings = []
    strings.extend(combinations(charset, length))
    return ["".join(string) for string in strings]

这个函数获取了每个长度对应的字符串列表

接着,我们用for循环就可以简单地实现我们想要的功能了

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,仅供参考

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,异步,多进程等.

免费评分

参与人数 5吾爱币 +11 热心值 +5 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
ellbaby + 1 + 1 我很赞同!
abc023119 + 1 + 1 谢谢@Thanks!
Yifan2007 + 1 + 1 我很赞同!
daoye9988 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 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
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
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-10 15:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表