Python编程快速上手第15章15.7.3蛮力PDF口令破解程序

题目:

假定有一个加密的PDF文档,你忘记了口令,但记得它是一个英语单词。尝试猜测遗 忘的口令是很无聊的任务。作为替代,你可以写一个程序,尝试用所有可能的英语单词来 解密这个PDF文档,直到找到有效的口令。这称为蛮力口令攻击。从异步社区本书对应页 面下载文本文件dictionary.txt。这个字典文件包含44 000多个英语单词,每个单词占一 行。

利用第9章学过的文件读取技巧来读取这个文件,并创建一个单词字符串的列表。然 后循环遍历这个列表中的每个单词,将它传递给decrypt()函数,如果这个函数返回整 数0,口令就是错的,程序应该继续尝试下一个口令。如果decrypt()函数返回1,程序 就应该终止循环,并输出破解的口令。你应该尝试每个单词的大小写形式(在我的笔记本 电脑上,遍历来自字典文件的88 000个大小写单词只要几分钟时间。这就是不应该使用简 单英语单词作为口令的原因)。

代码如下:

from PyPDF2 import PdfReader


def decrypt_pdf(password):
    # 为避免解密失败而报错,使用try-except语句
    try:
        with open('encrypt_file.pdf', 'rb') as file:    # 用读二进制模式打开需要解密的PDF文件
            pdfReader = PdfReader(file)

            # 检查PDF文件是否加密
            if pdfReader.is_encrypted:
                pdfReader.decrypt(password)
            # 检查是否可以获取PDF文件第1页的文本字符串
            if pdfReader.pages[0].extract_text():
                # 若能获取第1页的文本,则表示解密成功,返回1
                return 1
    except:
        # 若是解密失败,则跳过
        pass


def brute_force_attack(dictionary):
    with open(dictionary, 'r') as file:    # 用读模式打开含有所有口令的文件
        # 将每一个口令都存储在变量中
        words = file.read().splitlines()
    
    # 遍历每一个口令并开始破解
    for word in words:
        # 先尝试小写的口令
        if decrypt_pdf(word.lower()):
            print('Password is decrypted: ', word.lower())
            # 口令正确,则打印出来,并退出程序
            break
        # 再尝试全大写的口令
        elif decrypt_pdf(word.upper()):
            print('Password is decrypted: ', word.upper())
            break


# 调用破解口令的函数
brute_force_attack('dictionary.txt')    # dictionary.txt应替换为该文件的实际路径

你可能感兴趣的:(Python编程快速上手,python,pdf)