当前位置: 代码网 > it编程>编程语言>Asp.net > 基于C#实现rar文件密码破解工具

基于C#实现rar文件密码破解工具

2025年07月01日 Asp.net 我要评论
本文主要介绍了一个c#编写的rar压缩文件密码恢复工具,该程序通过加载密码字典文件,逐个尝试密码来破解受密码保护的rar文件。主要功能包括1.选择rar文件和密码字典2.显示恢复进度3.统计尝试密码数

本文主要介绍了一个c#编写的rar压缩文件密码恢复工具,该程序通过加载密码字典文件,逐个尝试密码来破解受密码保护的rar文件。

主要功能包括

1.选择rar文件和密码字典

2.显示恢复进度

3.统计尝试密码数量和速度

4.计算剩余时间

本工具采用后台线程运行密码破解过程,可以避免ui冻结,并提供取消操作功能。

效果图

程序代码

using system;
using system.collections.generic;
using system.componentmodel;
using system.diagnostics;
using system.drawing;
using system.io;
using system.linq;
using system.security.cryptography;
using system.windows.forms;
using sharpcompress.archives;
using sharpcompress.archives.rar;
using sharpcompress.common;
using sharpcompress.readers;

namespace rarpasswordrecovery
{
    public partial class mainform : form
    {
        private backgroundworker worker;
        private long totalpasswords;
        private long testedpasswords;
        private stopwatch stopwatch;
        private list<string> passwordlist;
        private bool passwordfound;
        private string foundpassword;
        private bool isrunning;

        public mainform()
        {
            initializecomponent();
            initializebackgroundworker();
            setupui();
        }

        private void initializebackgroundworker()
        {
            worker = new backgroundworker
            {
                workerreportsprogress = true,
                workersupportscancellation = true
            };
            worker.dowork += worker_dowork;
            worker.progresschanged += worker_progresschanged;
            worker.runworkercompleted += worker_runworkercompleted;
        }

        private void setupui()
        {
            // 设置窗体
            this.text = "rar密码恢复工具";
            this.size = new size(800, 500);
            this.minimumsize = new size(600, 400);
            this.backcolor = color.fromargb(45, 45, 65);
            this.forecolor = color.white;
            this.formborderstyle = formborderstyle.fixedsingle;
            this.startposition = formstartposition.centerscreen;

            // 创建控件
            createcontrols();
        }

        private void createcontrols()
        {
            // 标题标签
            label titlelabel = new label
            {
                text = "rar压缩文件密码恢复",
                font = new font("segoe ui", 16, fontstyle.bold),
                autosize = true,
                location = new point(20, 15),
                forecolor = color.lightskyblue
            };
            this.controls.add(titlelabel);

            // rar文件选择
            label lblrarfile = new label
            {
                text = "rar文件路径:",
                location = new point(20, 60),
                autosize = true
            };
            this.controls.add(lblrarfile);

            textbox txtrarfilepath = new textbox
            {
                location = new point(120, 57),
                size = new size(500, 25),
                name = "txtrarfilepath",
                readonly = true
            };
            this.controls.add(txtrarfilepath);

            button btnbrowserar = new button
            {
                text = "浏览...",
                location = new point(630, 55),
                size = new size(80, 25),
                name = "btnbrowserar",
                backcolor = color.fromargb(70, 70, 90),
                forecolor = color.white,
                flatstyle = flatstyle.flat
            };
            btnbrowserar.flatappearance.bordersize = 0;
            btnbrowserar.click += btnbrowserar_click;
            this.controls.add(btnbrowserar);

            // 字典文件选择
            label lbldictionary = new label
            {
                text = "密码字典文件:",
                location = new point(20, 100),
                autosize = true
            };
            this.controls.add(lbldictionary);

            textbox txtdictionarypath = new textbox
            {
                location = new point(120, 97),
                size = new size(500, 25),
                name = "txtdictionarypath",
                readonly = true
            };
            this.controls.add(txtdictionarypath);

            button btnbrowsedict = new button
            {
                text = "浏览...",
                location = new point(630, 95),
                size = new size(80, 25),
                name = "btnbrowsedict",
                backcolor = color.fromargb(70, 70, 90),
                forecolor = color.white,
                flatstyle = flatstyle.flat
            };
            btnbrowsedict.flatappearance.bordersize = 0;
            btnbrowsedict.click += btnbrowsedict_click;
            this.controls.add(btnbrowsedict);

            // 进度条
            progressbar progressbar = new progressbar
            {
                location = new point(20, 150),
                size = new size(690, 25),
                name = "progressbar",
                style = progressbarstyle.continuous
            };
            this.controls.add(progressbar);

            // 状态标签
            label lblstatus = new label
            {
                location = new point(20, 185),
                size = new size(690, 20),
                name = "lblstatus",
                text = "就绪",
                textalign = contentalignment.middleleft
            };
            this.controls.add(lblstatus);

            // 统计信息
            label lbltotal = new label
            {
                location = new point(20, 215),
                size = new size(200, 20),
                name = "lbltotalpasswords",
                text = "总密码数: 0"
            };
            this.controls.add(lbltotal);

            label lbltested = new label
            {
                location = new point(230, 215),
                size = new size(200, 20),
                name = "lbltested",
                text = "已尝试: 0"
            };
            this.controls.add(lbltested);

            label lblspeed = new label
            {
                location = new point(440, 215),
                size = new size(200, 20),
                name = "lblspeed",
                text = "速度: 0 p/s"
            };
            this.controls.add(lblspeed);

            // 时间信息
            label lblelapsed = new label
            {
                location = new point(20, 245),
                size = new size(200, 20),
                name = "lblelapsed",
                text = "已用时间: 00:00:00"
            };
            this.controls.add(lblelapsed);

            label lblremaining = new label
            {
                location = new point(230, 245),
                size = new size(200, 20),
                name = "lblremaining",
                text = "剩余时间: --:--:--"
            };
            this.controls.add(lblremaining);

            // 当前尝试密码
            label lblcurrent = new label
            {
                text = "当前尝试密码:",
                location = new point(20, 280),
                autosize = true
            };
            this.controls.add(lblcurrent);

            textbox txtcurrentpassword = new textbox
            {
                location = new point(120, 277),
                size = new size(500, 25),
                name = "txtcurrentpassword",
                readonly = true,
                font = new font("consolas", 10),
                backcolor = color.fromargb(30, 30, 40),
                forecolor = color.lightgreen
            };
            this.controls.add(txtcurrentpassword);

            // 按钮
            button btnstart = new button
            {
                text = "开始恢复",
                location = new point(200, 320),
                size = new size(120, 35),
                name = "btnstart",
                backcolor = color.seagreen,
                flatstyle = flatstyle.flat,
                font = new font("segoe ui", 10, fontstyle.bold)
            };
            btnstart.flatappearance.bordersize = 0;
            btnstart.click += btnstart_click;
            this.controls.add(btnstart);

            button btncancel = new button
            {
                text = "取消",
                location = new point(340, 320),
                size = new size(120, 35),
                name = "btncancel",
                enabled = false,
                backcolor = color.indianred,
                flatstyle = flatstyle.flat,
                font = new font("segoe ui", 10)
            };
            btncancel.flatappearance.bordersize = 0;
            btncancel.click += btncancel_click;
            this.controls.add(btncancel);

            // 法律声明
            linklabel linklegal = new linklabel
            {
                text = "使用条款和道德声明",
                location = new point(20, 370),
                autosize = true,
                linkcolor = color.lightskyblue,
                activelinkcolor = color.cyan
            };
            linklegal.linkclicked += linklegal_linkclicked;
            this.controls.add(linklegal);

            // 状态图标
            picturebox statusicon = new picturebox
            {
                location = new point(650, 320),
                size = new size(60, 60),
                sizemode = pictureboxsizemode.zoom
            };
            // 注意:在实际项目中,您需要添加自己的图标
            statusicon.backcolor = color.transparent;
            this.controls.add(statusicon);
        }

        private void btnbrowserar_click(object sender, eventargs e)
        {
            using (openfiledialog openfiledialog = new openfiledialog())
            {
                openfiledialog.filter = "rar files (*.rar)|*.rar|all files (*.*)|*.*";
                openfiledialog.title = "选择rar文件";

                if (openfiledialog.showdialog() == dialogresult.ok)
                {
                    gettextbox("txtrarfilepath").text = openfiledialog.filename;
                }
            }
        }

        private void btnbrowsedict_click(object sender, eventargs e)
        {
            using (openfiledialog openfiledialog = new openfiledialog())
            {
                openfiledialog.filter = "text files (*.txt)|*.txt|all files (*.*)|*.*";
                openfiledialog.title = "选择密码字典文件";

                if (openfiledialog.showdialog() == dialogresult.ok)
                {
                    gettextbox("txtdictionarypath").text = openfiledialog.filename;
                }
            }
        }

        private void btnstart_click(object sender, eventargs e)
        {
            textbox txtrarfilepath = gettextbox("txtrarfilepath");
            textbox txtdictionarypath = gettextbox("txtdictionarypath");

            if (string.isnullorwhitespace(txtrarfilepath.text))
            {
                messagebox.show("请选择rar文件", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }

            if (string.isnullorwhitespace(txtdictionarypath.text))
            {
                messagebox.show("请选择密码字典文件", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }

            if (!file.exists(txtrarfilepath.text))
            {
                messagebox.show("选择的rar文件不存在", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }

            if (!file.exists(txtdictionarypath.text))
            {
                messagebox.show("选择的字典文件不存在", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }

            // 重置ui
            passwordfound = false;
            foundpassword = null;
            testedpasswords = 0;
            isrunning = true;
            getprogressbar().value = 0;
            getlabel("lblstatus").text = "加载密码字典...";
            getlabel("lbltested").text = "已尝试: 0";
            getlabel("lblspeed").text = "速度: 0 p/s";
            getlabel("lblelapsed").text = "已用时间: 00:00:00";
            getlabel("lblremaining").text = "剩余时间: --:--:--";
            gettextbox("txtcurrentpassword").text = "";
            getbutton("btnstart").enabled = false;
            getbutton("btncancel").enabled = true;

            try
            {
                // 读取字典文件
                passwordlist = file.readalllines(txtdictionarypath.text)
                    .where(p => !string.isnullorwhitespace(p))
                    .distinct()
                    .tolist();

                totalpasswords = passwordlist.count;

                if (totalpasswords == 0)
                {
                    messagebox.show("字典文件为空", "错误", messageboxbuttons.ok, messageboxicon.error);
                    resetui();
                    return;
                }

                getlabel("lbltotalpasswords").text = $"总密码数: {totalpasswords:n0}";
                stopwatch = stopwatch.startnew();
                worker.runworkerasync();
            }
            catch (exception ex)
            {
                messagebox.show($"读取字典文件错误: {ex.message}", "错误", messageboxbuttons.ok, messageboxicon.error);
                resetui();
            }
        }

        private void worker_dowork(object sender, doworkeventargs e)
        {
            backgroundworker worker = sender as backgroundworker;
            passwordfound = false;
            foundpassword = null;
            string rarfilepath = gettextbox("txtrarfilepath").text;

            try
            {
                // 尝试每个密码
                for (int i = 0; i < passwordlist.count; i++)
                {
                    if (worker.cancellationpending)
                    {
                        e.cancel = true;
                        return;
                    }

                    string password = passwordlist[i];
                    testedpasswords++;

                    try
                    {
                        // 修复:使用readeroptions传递密码
                        var options = new readeroptions
                        {
                            password = password,
                            lookforheader = true,
                            disablecheckincomplete = true
                        };

                        // 尝试打开压缩文件
                        using (var archive = rararchive.open(rarfilepath, options))
                        {
                            // 尝试访问第一个文件
                            var entry = archive.entries.firstordefault();
                            if (entry != null)
                            {
                                // 尝试读取少量数据
                                using (var stream = entry.openentrystream())
                                {
                                    byte[] buffer = new byte[10];
                                    stream.read(buffer, 0, buffer.length);

                                    // 如果成功读取数据,密码正确
                                    passwordfound = true;
                                    foundpassword = password;
                                    return;
                                }
                            }
                        }
                    }
                    catch (sharpcompress.common.cryptographicexception)
                    {
                        // 密码错误,继续尝试
                    }
                    catch (invalidformatexception)
                    {
                        // 密码错误或文件格式问题
                    }
                    catch (exception ex)
                    {
                        // 其他错误,记录并继续尝试
                        worker.reportprogress(0, $"密码 '{password}' 尝试失败: {ex.message}");
                    }

                    // 每100次尝试报告一次进度
                    if (testedpasswords % 100 == 0)
                    {
                        int progress = (int)((double)testedpasswords / totalpasswords * 100);
                        worker.reportprogress(progress, password);
                    }
                }
            }
            catch (exception ex)
            {
                worker.reportprogress(0, $"错误: {ex.message}");
            }
        }

        private void worker_progresschanged(object sender, progresschangedeventargs e)
        {
            if (e.userstate is string currentpassword)
            {
                gettextbox("txtcurrentpassword").text = currentpassword;
            }

            getprogressbar().value = e.progresspercentage;
            getlabel("lbltested").text = $"已尝试: {testedpasswords:n0} / {totalpasswords:n0}";

            // 计算速度
            double seconds = stopwatch.elapsed.totalseconds;
            double passwordspersecond = seconds > 0 ? testedpasswords / seconds : 0;
            getlabel("lblspeed").text = $"速度: {passwordspersecond:n1} p/s";

            // 计算剩余时间
            if (passwordspersecond > 0)
            {
                long remaining = totalpasswords - testedpasswords;
                timespan remainingtime = timespan.fromseconds(remaining / passwordspersecond);
                getlabel("lblremaining").text = $"剩余时间: {remainingtime:hh\\:mm\\:ss}";
            }

            getlabel("lblelapsed").text = $"已用时间: {stopwatch.elapsed:hh\\:mm\\:ss}";
            getlabel("lblstatus").text = "正在尝试恢复密码...";
        }

        private void worker_runworkercompleted(object sender, runworkercompletedeventargs e)
        {
            stopwatch.stop();
            isrunning = false;

            if (e.cancelled)
            {
                getlabel("lblstatus").text = "操作已取消";
            }
            else if (e.error != null)
            {
                getlabel("lblstatus").text = $"错误: {e.error.message}";
            }
            else if (passwordfound)
            {
                getlabel("lblstatus").text = "密码已找到!";
                gettextbox("txtcurrentpassword").text = foundpassword;
                gettextbox("txtcurrentpassword").forecolor = color.lime;
                messagebox.show($"密码已找到: {foundpassword}", "成功",
                    messageboxbuttons.ok, messageboxicon.information);
            }
            else
            {
                getlabel("lblstatus").text = "在字典中未找到密码";
                gettextbox("txtcurrentpassword").text = "未找到匹配的密码";
            }

            getbutton("btnstart").enabled = true;
            getbutton("btncancel").enabled = false;
        }

        private void btncancel_click(object sender, eventargs e)
        {
            if (worker.isbusy)
            {
                worker.cancelasync();
                getbutton("btncancel").enabled = false;
                getlabel("lblstatus").text = "正在取消操作...";
            }
        }

        private void linklegal_linkclicked(object sender, linklabellinkclickedeventargs e)
        {
            messagebox.show("本工具仅供教育目的使用\n\n" +
                           "仅限您合法拥有的文件使用\n\n" +
                           "未经授权访问他人文件是违法行为\n\n" +
                           "使用本工具即表示您同意承担所有责任",
                           "法律和道德声明",
                           messageboxbuttons.ok,
                           messageboxicon.information);
        }

        private void resetui()
        {
            getbutton("btnstart").enabled = true;
            getbutton("btncancel").enabled = false;
        }

        // helper methods to get controls by name
        private textbox gettextbox(string name) => this.controls.find(name, true).firstordefault() as textbox;
        private label getlabel(string name) => this.controls.find(name, true).firstordefault() as label;
        private button getbutton(string name) => this.controls.find(name, true).firstordefault() as button;
        private progressbar getprogressbar() => this.controls.find("progressbar", true).firstordefault() as progressbar;
    }
}

 以上就是基于c#实现rar文件密码破解工具的详细内容,更多关于c#破解rar文件密码的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com