PDF 비밀번호 해제 [강제로 뚫기 1] PDF Password Remover [Forcible Cracking Method]

PDF 비밀번호 해제 (코딩 및 exe 실행 파일)

암호를 잊어 버렸을 때 어떻게든 찾아보자

PDF 비밀번호 해제! 본인이 가지고 있는 문서를 열려고 했는데 비밀번호를 잊어버려 열 수 없는 경우가 있습니다. 꼭 열어야 하는 PDF라면 당황스러운데요. 그런 경우 유용한 코드 및 실행 파일 입니다. 보안 걱정 없도록 코드도 모두 공개했습니다. 안심하세요~

(저는 코딩에 대해 잘 모르며, 아래의 코딩은 GPT로 작성하였습니다.)

PDF 비밀번호 해제

작동방식

PDF 비밀번호 해제 작동 방식은 아주 간단합니다. 모든 경우의 수를 일일이 대입합니다. 그래도 그나마 최대한 빠르게 찾기 위해 암호의 오름차순, 내림차순으로 두방향을 동시에 찾습니다.

미리 말씀드리지만 하나씩 대조하기 때문에 매우 매우 오래 걸립니다. 하지만 꼭 필요한 문서라면 시간을 들여서라도 꼭 열어야겠죠!! (그나마 빠르게 대조 하기 위해 멀티쓰레드를 이용했습니다)

사용방법

PDF 비밀번호 해제 프로그램 설명을 드리면 Input pdf를 통해 암호를 해제하고자 하는 파일을 불러옵니다.

  • output pdf는 해제한 pdf를 저장합니다.
  • include number(‘0123456789’) 는 암호에 숫자만 포함된 경우 체크해 줍니다. 예를 들어 내가 기억은 안나지만 전화번호 또는 생년월일 이렇게 숫자만으로 암호를 저장했다면 이부분만 체크해 주시면 됩니다.
  • include latters(‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’) 문자까지 포함한경우 체크해줍니다.
  • include special characters (‘!@#$%^&*()’) 특수문자까지 포함한경우 체크해줍니다.
  • start end range는 글짜 수를 말합니다 예를 들어 내가 잘은 모르지만 5글짜 이상 8글짜 이하라면 star를 5 end를8을 입력시켜주면 됩니다.

실행파일

PDF 비밀번호 해제 exe 실행 파일은 댓글에 메일주소를 남겨주시면 보내드리겠습니다.

코드

PDF 비밀번호 해제 코드는 python으로 작성되었습니다.

import pikepdf
import tkinter as tk
from tkinter import filedialog
from tkinter import ttk
import threading
import queue

stop_flag = threading.Event()

def select_input_pdf():
    input_pdf_path = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")])
    input_pdf.set(input_pdf_path)
    input_pdf_display.config(text=input_pdf_path)

def select_output_pdf():
    output_pdf_path = filedialog.asksaveasfilename(defaultextension='.pdf', filetypes=[("PDF Files", "*.pdf")])
    output_pdf.set(output_pdf_path)
    output_pdf_display.config(text=output_pdf_path)

def brute_force_remove_pdf_password():
    def generate_passwords(characters, start, end):
        import itertools
        for password_length in range(start, end + 1):
            for password in itertools.product(characters, repeat=password_length):
                if stop_flag.is_set():
                    return
                yield ''.join(password)

    def worker(password_queue, characters, input_path, output_path, total_attempts, start, end):
        for attempt, password in enumerate(generate_passwords(characters, start, end), start=1):
            password_queue.put((attempt, password))
            try:
                pdf = pikepdf.Pdf.open(input_path, password=password)
                pdf.save(output_path)
                pdf.close()
                password_queue.put("found")
                return
            except pikepdf.PasswordError:
                continue
        password_queue.put("not found")

    def update_progress(password_queue, total_attempts):
        password_dict = {}
        found_password = None
        while True:
            message = password_queue.get()

            if isinstance(message, tuple):
                attempt, password = message
                progress["value"] = attempt
                progress.update()

                progress_text.set(f"{attempt / total_attempts * 100:.2f}% - {password}")
                progress_label.update()

                # 스레드가 찾은 암호 저장
                if found_password is None:
                    password_dict[password] = attempt

                    # 두 스레드가 동일한 암호를 찾으면 작업 중지
                    if password in password_dict and password_dict[password] != attempt:
                        stop_brute_force()
                        return
            elif message == "found":
                result_label.config(text=f"암호가 해제되었습니다. 암호: {found_password}")
                break
            elif message == "not found":
                result_label.config(text="탐색한 암호로는 암호가 해제되지 않았습니다.")
                break
            elif message == "stopped":
                result_label.config(text="작업이 중지되었습니다.")
                break

            password_queue.task_done()

    characters = ''
    if numbers.get() == 1:
        characters += '0123456789'
    if letters.get() == 1:
        characters += 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    if special_chars.get() == 1:
        characters += '!@#$%^&*()'

    input_path = input_pdf.get()
    output_path = output_pdf.get()

    total_attempts = len(characters) ** end_range.get() - len(characters) ** (start_range.get() - 1)
    progress["maximum"] = total_attempts
    progress["value"] = 0

    stop_flag.clear()
    password_queue = queue.Queue()
    middle_range = (start_range.get() + end_range.get()) // 2
    t1 = threading.Thread(target=worker, args=(password_queue, characters, input_path, output_path, total_attempts, start_range.get(), middle_range))
    t2 = threading.Thread(target=worker, args=(password_queue, characters, input_path, output_path, total_attempts, middle_range + 1, end_range.get()))
    t3 = threading.Thread(target=update_progress, args=(password_queue, total_attempts))
    t1.start()
    t2.start()
    t3.start()

def stop_brute_force():
    stop_flag.set()

root = tk.Tk()
root.title("PDF Password Remover")
input_pdf = tk.StringVar()
output_pdf = tk.StringVar()
numbers = tk.IntVar()
letters = tk.IntVar()
special_chars = tk.IntVar()
start_range = tk.IntVar(value=1)
end_range = tk.IntVar(value=7)
progress_text = tk.StringVar(value="")

input_pdf_label = tk.Label(root, text="Input PDF:")
input_pdf_label.grid(row=0, column=0, sticky="w")
input_pdf_display = tk.Label(root, text="")
input_pdf_display.grid(row=0, column=1, sticky="w")
input_pdf_button = tk.Button(root, text="Select", command=select_input_pdf)
input_pdf_button.grid(row=0, column=2)

output_pdf_label = tk.Label(root, text="Output PDF:")
output_pdf_label.grid(row=1, column=0, sticky="w")
output_pdf_display = tk.Label(root, text="")
output_pdf_display.grid(row=1, column=1, sticky="w")
output_pdf_button = tk.Button(root, text="Select", command=select_output_pdf)
output_pdf_button.grid(row=1, column=2)

options_frame = tk.Frame(root)
options_frame.grid(row=2, column=0, columnspan=2, pady=(10, 0))

numbers_checkbox = tk.Checkbutton(options_frame, text="Include numbers", variable=numbers)
numbers_checkbox.grid(row=0, column=0)
letters_checkbox = tk.Checkbutton(options_frame, text="Include letters", variable=letters)
letters_checkbox.grid(row=0, column=1)
special_chars_checkbox = tk.Checkbutton(options_frame, text="Include special characters", variable=special_chars)
special_chars_checkbox.grid(row=0, column=2)

start_range_label = tk.Label(options_frame, text="Start Password Range:")
start_range_label.grid(row=1, column=0, sticky="w")
start_range_entry = tk.Entry(options_frame, textvariable=start_range, width=5)
start_range_entry.grid(row=1, column=1, sticky="w")

end_range_label = tk.Label(options_frame, text="End Password Range:")
end_range_label.grid(row=2, column=0, sticky="w")
end_range_entry = tk.Entry(options_frame, textvariable=end_range, width=5)
end_range_entry.grid(row=2, column=1, sticky="w")

progress = ttk.Progressbar(root, mode="determinate")
progress.grid(row=3, column=0, columnspan=3, pady=(10, 0), sticky="ew")

progress_label = tk.Label(root, textvariable=progress_text)
progress_label.grid(row=4, column=0, columnspan=3, pady=(10, 0))

run_button = tk.Button(root, text="Remove Password", command=brute_force_remove_pdf_password)
run_button.grid(row=5, column=0)

stop_button = tk.Button(root, text="Stop", command=stop_brute_force)
stop_button.grid(row=5, column=2)

result_label = tk.Label(root, text="")
result_label.grid(row=6, column=0, columnspan=3, pady=(10, 0))

root.mainloop()

PDF Password Removal [Forcible Cracking Method]

Sometimes, there are situations where you forget the password to open a document you own, and you cannot access the content. It can be quite frustrating, especially if it’s an important PDF that you urgently need to open. In such cases, the code and executable provided here can be very useful.

leave your email in the comments, and I will send you the executable file.

단순하게 암호를 알고있지만 해제만 하고 싶으면 이 사이트를 이용하세요

다른 취미코딩도 소개해 드려요

2 thoughts on “PDF 비밀번호 해제 [강제로 뚫기 1] PDF Password Remover [Forcible Cracking Method]”

  1. 유용한 정보 감사드립니다. 시간 괜찮으시면 아래 이메일로 실행파일 보내주시면 감사하겠습니다^^

    좋은 하루 보내세요~

    응답

댓글 남기기