乐于分享
好东西不私藏

PDF处理——PyPDF2加密与解密

PDF处理——PyPDF2加密与解密

一、加密PDF

1.1 基本加密

import PyPDF2defencrypt_pdf(filepath, output_path, password):"""加密PDF文件"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)        writer = PyPDF2.PdfWriter()for page in reader.pages:            writer.add_page(page)        writer.encrypt(password)withopen(output_path, 'wb'as output:            writer.write(output)print(f"PDF已加密: {output_path}")# 使用encrypt_pdf('document.pdf''encrypted.pdf''password123')

1.2 不同加密算法

import PyPDF2defencrypt_with_algorithm(filepath, output_path, password, algorithm='AES-256'):"""    使用不同算法加密    算法: 'AES-256', 'RC4-128'    """withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)        writer = PyPDF2.PdfWriter()for page in reader.pages:            writer.add_page(page)# PyPDF2使用AES-256作为默认# 通过use_aes=True启用AES-256if algorithm == 'AES-256':            writer.encrypt(password, use_aes=True)else:            writer.encrypt(password, use_aes=False)withopen(output_path, 'wb'as output:            writer.write(output)print(f"使用{algorithm}加密完成: {output_path}")# 使用不同算法encrypt_with_algorithm('document.pdf''aes_encrypted.pdf''password''AES-256')encrypt_with_algorithm('document.pdf''rc4_encrypted.pdf''password''RC4-128')

1.3 设置不同权限

import PyPDF2defencrypt_with_permissions(filepath, output_path, user_password, owner_password=None):"""加密并设置权限"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)        writer = PyPDF2.PdfWriter()for page in reader.pages:            writer.add_page(page)# 设置权限        permissions = {'print'False,          # 禁止打印'extract'False,        # 禁止提取文本'modify'False,         # 禁止修改'copy'False,           # 禁止复制'annotate'False,       # 禁止注释'fill_forms'False,     # 禁止填写表单'accessibility'False,  # 禁止无障碍访问'assemble'False,       # 禁止文档组装'print_high_res'False# 禁止高分辨率打印        }# 设置权限标志if owner_password isNone:            owner_password = user_password        writer.encrypt(            user_password=user_password,            owner_password=owner_password,            permissions_flag=0# 禁止所有操作        )withopen(output_path, 'wb'as output:            writer.write(output)print(f"带权限加密完成: {output_path}")# 使用encrypt_with_permissions('document.pdf''restricted.pdf''user123''owner456')

二、解密PDF

2.1 基本解密

import PyPDF2defdecrypt_pdf(filepath, output_path, password):"""解密PDF文件"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)if reader.is_encrypted:            reader.decrypt(password)            writer = PyPDF2.PdfWriter()for page in reader.pages:                writer.add_page(page)withopen(output_path, 'wb'as output:                writer.write(output)print(f"PDF已解密: {output_path}")else:print("文件未加密")# 使用decrypt_pdf('encrypted.pdf''decrypted.pdf''password123')

2.2 尝试多种密码

import PyPDF2defdecrypt_with_try(filepath, output_path, password_list):"""尝试多种密码解密"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)ifnot reader.is_encrypted:print("文件未加密")returnfor password in password_list:try:                reader.decrypt(password)# 验证是否解密成功ifnot reader.is_encrypted:                    writer = PyPDF2.PdfWriter()for page in reader.pages:                        writer.add_page(page)withopen(output_path, 'wb'as output:                        writer.write(output)print(f"解密成功! 密码: {password}")returnexcept Exception:continueprint("所有密码尝试失败")# 使用passwords = ['123456''password''admin''12345''secret']decrypt_with_try('encrypted.pdf''decrypted.pdf', passwords)

2.3 检查加密信息

import PyPDF2defget_encryption_info(filepath):"""获取PDF加密信息"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)        info = {'is_encrypted': reader.is_encrypted,        }if reader.is_encrypted:# 获取加密信息            info['encryption_version'] = getattr(reader, 'encryption_version''Unknown')# 检查是否有权限限制try:# 尝试读取页面                reader.pages[0]                info['has_permissions'] = Trueexcept Exception:                info['has_permissions'] = Falsereturn info# 使用info = get_encryption_info('encrypted.pdf')print("加密信息:")for key, value in info.items():print(f"  {key}{value}")

三、密码管理

3.1 批量加密

import PyPDF2from pathlib import Pathimport osdefbatch_encrypt(folder_path, output_dir, password):"""批量加密PDF文件"""    os.makedirs(output_dir, exist_ok=True)    pdf_files = list(Path(folder_path).glob('*.pdf'))for pdf_path in pdf_files:try:withopen(pdf_path, 'rb'as file:                reader = PyPDF2.PdfReader(file)                writer = PyPDF2.PdfWriter()for page in reader.pages:                    writer.add_page(page)                writer.encrypt(password)                output_path = os.path.join(output_dir, pdf_path.name)withopen(output_path, 'wb'as output:                    writer.write(output)print(f"已加密: {pdf_path.name}")except Exception as e:print(f"加密失败: {pdf_path.name} - {e}")# 使用batch_encrypt('./pdfs''./encrypted''batch_password')

3.2 批量解密

import PyPDF2from pathlib import Pathimport osdefbatch_decrypt(folder_path, output_dir, password):"""批量解密PDF文件"""    os.makedirs(output_dir, exist_ok=True)    pdf_files = list(Path(folder_path).glob('*.pdf'))for pdf_path in pdf_files:try:withopen(pdf_path, 'rb'as file:                reader = PyPDF2.PdfReader(file)if reader.is_encrypted:                    reader.decrypt(password)                writer = PyPDF2.PdfWriter()for page in reader.pages:                    writer.add_page(page)                output_path = os.path.join(output_dir, pdf_path.name)withopen(output_path, 'wb'as output:                    writer.write(output)print(f"已解密: {pdf_path.name}")except Exception as e:print(f"解密失败: {pdf_path.name} - {e}")# 使用batch_decrypt('./encrypted''./decrypted''batch_password')

四、密码破解(仅用于合法用途)

4.1 暴力破解

import PyPDF2import itertoolsimport stringdefbrute_force_pdf(filepath, max_length=4):"""暴力破解PDF密码(仅用于合法测试)"""    chars = string.ascii_lowercase + string.digitswithopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)ifnot reader.is_encrypted:print("文件未加密")returnNonefor length inrange(1, max_length + 1):print(f"尝试长度 {length}...")for password in itertools.product(chars, repeat=length):                password_str = ''.join(password)try:                    reader = PyPDF2.PdfReader(file)                    reader.decrypt(password_str)# 验证是否成功ifnot reader.is_encrypted:print(f"密码找到: {password_str}")return password_strexcept Exception:continueprint("未找到密码")returnNone# 使用(仅用于测试)# brute_force_pdf('encrypted.pdf', max_length=3)

4.2 字典攻击

import PyPDF2defdictionary_attack(filepath, wordlist_path):"""字典攻击破解PDF密码"""withopen(filepath, 'rb'as file:        reader = PyPDF2.PdfReader(file)ifnot reader.is_encrypted:print("文件未加密")returnNonewithopen(wordlist_path, 'r', encoding='utf-8'as f:for line in f:                password = line.strip()try:# 重新打开文件withopen(filepath, 'rb'as f2:                        reader2 = PyPDF2.PdfReader(f2)                        reader2.decrypt(password)ifnot reader2.is_encrypted:print(f"密码找到: {password}")return passwordexcept Exception:continueprint("未找到密码")returnNone# 使用# dictionary_attack('encrypted.pdf', 'wordlist.txt')

五、实战案例

5.1 安全文档处理系统

import PyPDF2import osfrom pathlib import Pathimport hashlibfrom datetime import datetimeclassSecurePDFProcessor:"""安全PDF处理系统"""def__init__(self, master_password):self.master_password = master_passwordself.processed_files = []defencrypt_file(self, filepath, output_dir='encrypted'):"""加密文件"""        os.makedirs(output_dir, exist_ok=True)# 生成基于文件内容的密码        file_hash = self._generate_file_hash(filepath)        password = f"{self.master_password}_{file_hash[:8]}"withopen(filepath, 'rb'as file:            reader = PyPDF2.PdfReader(file)            writer = PyPDF2.PdfWriter()for page in reader.pages:                writer.add_page(page)            writer.encrypt(password)            output_path = os.path.join(output_dir, Path(filepath).name)withopen(output_path, 'wb'as output:                writer.write(output)self.processed_files.append({'file': filepath,'encrypted_file': output_path,'password': password,'timestamp': datetime.now()            })print(f"已加密: {Path(filepath).name}")return output_pathdefdecrypt_file(self, filepath, output_dir='decrypted'):"""解密文件"""        os.makedirs(output_dir, exist_ok=True)# 查找对应的加密信息        encrypted_info = Nonefor info inself.processed_files:if info['encrypted_file'] == filepath:                encrypted_info = infobreakifnot encrypted_info:print("未找到加密信息")returnNonewithopen(filepath, 'rb'as file:            reader = PyPDF2.PdfReader(file)if reader.is_encrypted:                reader.decrypt(encrypted_info['password'])            writer = PyPDF2.PdfWriter()for page in reader.pages:                writer.add_page(page)            output_path = os.path.join(output_dir, Path(filepath).name)withopen(output_path, 'wb'as output:                writer.write(output)print(f"已解密: {Path(filepath).name}")return output_pathdef_generate_file_hash(self, filepath):"""生成文件哈希"""        hasher = hashlib.sha256()withopen(filepath, 'rb'as f:for chunk initer(lambda: f.read(4096), b''):                hasher.update(chunk)return hasher.hexdigest()defget_encrypted_files(self):"""获取已加密文件列表"""returnself.processed_filesdefgenerate_report(self, output_path='encryption_report.txt'):"""生成加密报告"""withopen(output_path, 'w', encoding='utf-8'as f:            f.write("PDF加密处理报告\n")            f.write("="*50 + "\n")            f.write(f"生成时间: {datetime.now()}\n")            f.write(f"处理文件数: {len(self.processed_files)}\n")            f.write("="*50 + "\n\n")for i, info inenumerate(self.processed_files, 1):                f.write(f"文件 {i}:\n")                f.write(f"  原始文件: {info['file']}\n")                f.write(f"  加密文件: {info['encrypted_file']}\n")                f.write(f"  密码: {info['password']}\n")                f.write(f"  时间: {info['timestamp']}\n")                f.write("\n")# 使用processor = SecurePDFProcessor('master_key_2024')processor.encrypt_file('document.pdf')processor.encrypt_file('report.pdf')processor.generate_report()

5.2 批量加密工具

import PyPDF2import osfrom pathlib import Pathimport csvimport jsonclassBatchEncryptionTool:"""批量加密工具"""def__init__(self, password_file='passwords.csv'):self.password_file = password_fileself.password_map = {}self._load_passwords()def_load_passwords(self):"""加载密码映射"""if os.path.exists(self.password_file):withopen(self.password_file, 'r', encoding='utf-8'as f:                reader = csv.reader(f)for row in reader:iflen(row) >= 2:self.password_map[row[0]] = row[1]def_save_passwords(self):"""保存密码映射"""withopen(self.password_file, 'w', newline='', encoding='utf-8'as f:            writer = csv.writer(f)for filename, password inself.password_map.items():                writer.writerow([filename, password])defencrypt_files(self, folder_path, output_dir='encrypted'):"""批量加密"""        os.makedirs(output_dir, exist_ok=True)        pdf_files = list(Path(folder_path).glob('*.pdf'))for pdf_path in pdf_files:            filename = pdf_path.name# 使用已有密码或生成新密码if filename inself.password_map:                password = self.password_map[filename]else:                password = self._generate_password()self.password_map[filename] = passwordtry:withopen(pdf_path, 'rb'as file:                    reader = PyPDF2.PdfReader(file)                    writer = PyPDF2.PdfWriter()for page in reader.pages:                        writer.add_page(page)                    writer.encrypt(password)                    output_path = os.path.join(output_dir, filename)withopen(output_path, 'wb'as output:                        writer.write(output)print(f"已加密: {filename}")except Exception as e:print(f"加密失败: {filename} - {e}")self._save_passwords()print(f"密码已保存到: {self.password_file}")def_generate_password(self):"""生成随机密码"""import randomimport string        chars = string.ascii_letters + string.digitsreturn''.join(random.choice(chars) for _ inrange(12))defget_password(self, filename):"""获取文件密码"""returnself.password_map.get(filename)# 使用tool = BatchEncryptionTool('encryption_passwords.csv')tool.encrypt_files('./pdfs')# 获取特定文件密码password = tool.get_password('document.pdf')print(f"document.pdf 密码: {password}")

六、注意事项

6.1 错误处理

import PyPDF2defsafe_encrypt(filepath, output_path, password):"""安全的加密操作"""try:withopen(filepath, 'rb'as file:            reader = PyPDF2.PdfReader(file)# 检查PDF是否已加密if reader.is_encrypted:print("文件已加密")return            writer = PyPDF2.PdfWriter()for page in reader.pages:                writer.add_page(page)            writer.encrypt(password)withopen(output_path, 'wb'as output:                writer.write(output)print(f"加密成功: {output_path}")except FileNotFoundError:print(f"文件不存在: {filepath}")except PyPDF2.errors.PdfReadError:print(f"无效的PDF文件: {filepath}")except Exception as e:print(f"加密失败: {e}")# 使用safe_encrypt('document.pdf''encrypted.pdf''password')

6.2 密码安全

import hashlibimport base64defsecure_password(password):"""安全处理密码"""# 使用SHA-256哈希    hashed = hashlib.sha256(password.encode()).hexdigest()return hasheddefsave_password_secure(password, output_path):"""安全保存密码"""import jsonfrom datetime import datetime    data = {'password': secure_password(password),'timestamp': datetime.now().isoformat(),'note''PDF encryption password'    }withopen(output_path, 'w'as f:        json.dump(data, f, indent=2)

七、总结

# 快速参考# 1. 加密PDFwriter = PyPDF2.PdfWriter()writer.encrypt(password)writer.encrypt(user_password, owner_password)# 2. 使用AES-256writer.encrypt(password, use_aes=True)# 3. 解密PDFreader.decrypt(password)# 4. 检查加密状态if reader.is_encrypted:print("文件已加密")# 5. 批量处理for pdf in pdf_files:    reader = PyPDF2.PdfReader(pdf)if reader.is_encrypted:        reader.decrypt(password)# 6. 安全建议# - 使用强密码(大小写字母+数字+特殊字符)# - 定期更换密码# - 备份原始文件# - 记录加密信息(安全保存)

PyPDF2提供了完整的PDF加密与解密功能,可以保护敏感文档的安全。加密时建议使用强密码和AES-256算法;解密时需确保有正确的密码。在批量处理时,注意密码的安全管理和备份。合理使用加密功能可以保护PDF文档的内容安全。