社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

实用脚本!利用 Python 对 PDF 进行加密、解密操作,代码拿走就用!

Python极客专栏 • 4 年前 • 373 次点击  
点击关注公众号,Python干货及时送达

PyCharm操作手册,点击获取

本文将分享如何利用 Python 对 PDF 进行加密和解密操作,主要利用到之前多次介绍过的PyPDF2 模块。

PDF 加密

在之前的文章PDF合并、拆分、水印、加密中简单提到过加密一个 PDF 文件的方法,我们先拿自己随意的一个PDF 文件试一下:

from PyPDF2 import PdfFileWriter, PdfFileReader
path = r'C:\xxx' # 这里填写目标 PDF 所在的路径

pdf_reader = PdfFileReader(path + r'\test.pdf')
pdf_writer = PdfFileWriter()

for page in range(pdf_reader.getNumPages()):
    pdf_writer.addPage(pdf_reader.getPage(page))
pdf_writer.encrypt('a123'# 设置密码为 a123
with open(path + r'\test.pdf''wb'as out:
    pdf_writer.write(out)

上面代码的运行逻辑是:实例化一个 PDF 写入器和读取器,读取器读取完目标 PDF 文件后,一页一页交给写入器,然后对写入器设置密码并输出。看一下运行结果:

可见这个 PDF 文件成功设置上了密码,如果有多个PDF需要加密,可以写一个简单的循环利用上述脚本批量处理,此处不再展开说明。

PDF 已知密码解密

如果知道密码的情况下,想直接取消 PDF 的加密,可以用 .decrypt,解密的过程需要读取器和写入器共同配合。但区别于加密 .encrypt.decrypt 是针对读取器进行解密的,而不是写入器

from PyPDF2 import PdfFileWriter, PdfFileReader
path = r'C:\xxx'

pdf_reader = PdfFileReader(path + r'\test.pdf')
pdf_reader.decrypt('a123'#
pdf_writer = PdfFileWriter()

for page in range(pdf_reader.getNumPages()):
    pdf_writer.addPage(pdf_reader.getPage(page))
with open(path + r'\test.pdf''wb'as out:
    pdf_writer.write(out)

上面代码的运行逻辑是:首先用读取器读取加密文件,然后直接在读取器上使用 .decrypt 进行解密,逐页传到刚实例化的写入器后统一输出,就完成了解密

PDF 暴力解密

暴力破解,其实就是通过手上已经有的密码库,或者完全通过数字、字母、符号的穷举,将可能的密码都放进去,逐个尝试直到成功。

「目前暴力破解只适用于已知密码位数少,由简单的数字、字母构成」

假设今天要破解的密码就是 a123,已知密码 4 位且由数字和小写字母组成。破解又分为两种情况:

1. 手上有密码本

第一种情况,知道大概密码,可以整理成一个 password.txt ,保证可能的密码一定在其中:

首先读取 .txt 文件获取其中所有密码(示例文件只有 9 个密码):

passw = []
path = r'C:\Scientific Research\Python'
file = open(path + r'\password.txt')
for line in file.readlines():
    passw.append(line.strip())
print(passw)
file.close()

然后就可以用密码本的密码做暴力破解:

from PyPDF2 import PdfFileReader

passw = []
path = r'C:\xxx'
file = open(path + r'\password.txt')
for line in file.readlines():
    passw.append(line.strip())
file.close()

path = r'C:\xxx'
pdf_reader = PdfFileReader(path + r'\test).pdf')

for i in passw:
    if pdf_reader.decrypt(i):
        print(f'破解成功,密码为{i}')
    else:
        print(f'破解不成功,密码{i}错误')

2. 手术无密码本,完全穷举

首先介绍 itertools,可以构建含需要组合的生成器供后续迭代:

import itertools
mylist = ("".join(x) for x in itertools.product("0123456789abcdef", repeat=4))
print(next(mylist))

利用这个方法就可以用 while 循环尝试暴力破解(为了减少时间,生成器用"abc123"生成组合):

import itertools
from PyPDF2 import PdfFileReader

mylist = ("".join(x) for x in itertools.product("123abc", repeat=4))
path = r'C:\xxx'
pdf_reader = PdfFileReader(path + r'\test.pdf')

while True:
    i = next(mylist)
    if pdf_reader.decrypt(i):
        print(f'破解成功,密码为{i}')
        break
    else:
        print(f'破解不成功,密码{i}错误')

可以看到最后也成功破解了,但需要注意:但即使是这么简单的组合也耗费了一点时间,如果复杂的密码破解难度和破解时间就指数级增长了,暴力的穷举法就不一定适用,可以根据需求具体调整规则,缩小范围再进行尝试。


如有文章对你有帮助,

在看”和转发是对我最大的支持!



关注Python极客专栏


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/115946
 
373 次点击