Шифрование и расшифровка PDF в Python с PyMuPDF

Неавторизованный доступ к конфиденциальным файлам — распространённая проблема. Чтобы доступ к содержимому файла имели только уполномоченные, полезно зашифровать файл перед отправкой. В этой инструкции показано, как зашифровать PDF и затем расшифровать его обратно с помощью Python и PyMuPDF.
Кому будет полезно
- Разработчикам, которым нужно добавить простой механизм защиты PDF-файлов.
- Сисадминам, которые автоматизируют процесс распространения защищённых документов.
- Тестировщикам, проверяющим поведение системы с защищёнными файлами.
Установка окружения
Требуется базовое знание Python и установленный pip. В терминале macOS или в командной строке Windows выполните:
pip install PyMuPDFЭта библиотека поможет открывать, редактировать и сохранять PDF. На иллюстрации ниже показан пример установки в терминале IDE.
После установки можно приступать к коду. Полный исходный код доступен в репозитории на GitHub (в статье даются все необходимые фрагменты).
Импорт и подготовка
Импортируем модуль fitz из PyMuPDF и добавим небольшую вспомогательную обёртку для совместимости API разных версий библиотеки.
import fitz # PyMuPDF
def pdf_is_encrypted(path):
"""Возвращает True, если документ зашифрован. Поддерживает разные версии PyMuPDF."""
pdf = fitz.open(path)
# API именования может отличаться: is_encrypted или isEncrypted
return bool(getattr(pdf, 'is_encrypted', getattr(pdf, 'isEncrypted', False)))Короткое определение: AES-256 — алгоритм симметричного шифрования, реализующий сильную защиту при условии безопасного пароля.
Функция шифрования PDF
Функция шифрует файл только если он ещё не зашифрован. В примере мы используем AES-256, доступный в PyMuPDF.
def encrypt_pdf_file(input_path, password, outfile):
"""Зашифровать PDF с сохранением в outfile. Если уже зашифрован — ничего не делать."""
if not pdf_is_encrypted(input_path):
pdf = fitz.open(input_path)
perm = int(
fitz.PDF_PERM_ACCESSIBILITY # доступность для специальных средств
| fitz.PDF_PERM_PRINT # печать
| fitz.PDF_PERM_COPY # копирование
| fitz.PDF_PERM_ANNOTATE # аннотирование
)
encrypt_meth = fitz.PDF_ENCRYPT_AES_256
# Сохраняем зашифрованную версию
pdf.save(outfile, encryption=encrypt_meth, user_pw=password, permissions=perm)
print("PDF зашифрован:", outfile)
else:
print("Файл уже зашифрован.")Вызывая эту функцию, вы получите файл protected.pdf (или любое имя, которое зададите) с установленным паролем.
Функция расшифровки PDF
Функция проверяет, защищён ли файл, затем запрашивает пароль и пытается расшифровать. В разных версиях PyMuPDF доступно метод authenticate; пример учитывает этот сценарий.
def decrypt_pdf(input_path, out_path='decrypted.pdf'):
"""Расшифровать PDF и сохранить в out_path. Вернёт True при успехе."""
if not pdf_is_encrypted(input_path):
print("Файл не защищён, расшифровка не требуется.")
return False
password = input('Введите пароль для PDF: ')
pdf = fitz.open(input_path)
# Попробуем аутентифицировать (метод зависит от версии библиотеки)
authenticated = getattr(pdf, 'authenticate', lambda pw: False)(password)
if authenticated:
pdf.save(out_path)
print("PDF расшифрован и сохранён как:", out_path)
return True
else:
print('Неверный пароль или расшифровка не удалась.')
return FalseВ результате вы получите незашифрованную копию файла в текущей рабочей папке по умолчанию.
Строка выше показывает, что protected.pdf был расшифрован и сохранён как decrypted.pdf.
Управление потоком программы
Пример основной функции, которая вызывает шифрование и расшифровку. Подставьте собственные пути и пароли.
def main():
file = 'sample.pdf' # путь к исходному PDF
password = 'pass123' # используйте сложный пароль в реальной жизни
encrypt_pdf_file(file, password, 'protected.pdf')
decrypt_pdf('protected.pdf')
if __name__ == '__main__':
main()Внимание: не храните пароли в открытом коде. В примере пароль задан статически только для демонстрации.
Отладка и частые ошибки
- Неправильный пароль: программа корректно сообщает об ошибке аутентификации.
- Версия PyMuPDF: некоторые имена атрибутов могли измениться (isEncrypted → is_encrypted, authenticate → другой метод). В коде выше добавлены проверки совместимости.
- Права записи: убедитесь, что директория для сохранения доступна для записи.
Альтернативные подходы
- PyPDF2 / pypdf: можно использовать для простого шифрования/дешифрования, но функциональность и производительность могут отличаться.
- qpdf (CLI): утилита командной строки для надёжной обработки и шифрования PDF.
- Слой файловой системы: шифрование на уровне диска (BitLocker, FileVault) или архивирование (zip с паролем) для защиты набора файлов.
Безопасность и лучшие практики
- Используйте надёжные пароли: длина ≥ 12 символов, сочетание букв, цифр и символов.
- Не храните пароли в исходниках; используйте менеджеры секретов или переменные окружения.
- Контролируйте права доступа к зашифрованным файлам на файловой системе и в пересылаемых каналах.
- Для корпоративной защиты применяйте управление ключами (KMS) и централизованные решения.
Важно: шифрование PDF защищает содержимое документа, но метаданные и имена файлов могут быть видимы до установки дополнительных мер.
Тесты приёмки
Критерии приёмки для функции шифрования/расшифровки:
- Шифрование:
- Входной файл не зашифрован → вызываем encrypt_pdf_file → получаем файл outfile, pdf_is_encrypted(outfile) == True.
- Входной файл уже зашифрован → функция не перезаписывает его и выводит соответствующее сообщение.
- Расшифровка:
- Неверный пароль → функция возвращает False и файл не создаётся.
- Правильный пароль → создаётся out_path, pdf_is_encrypted(out_path) == False.
Пример тест-кейса для QA:
- Подготовить sample.pdf (незашифрованный).
- Запустить encrypt_pdf_file(sample.pdf, ‘testpass’, ‘protected.pdf’).
- Проверить, что protected.pdf открывается только с паролем ‘testpass’.
- Запустить decrypt_pdf(‘protected.pdf’). Ввести ‘testpass’. Проверить, что decrypted.pdf существует и не зашифрован.
Контроль качества и рольовые чек-листы
Разработчик:
- Убедиться в обработке исключений (IOError, ошибки PyMuPDF).
- Добавить логирование без вывода паролей.
- Написать модульные тесты для api-обёртки.
Инженер по безопасности:
- Убедиться, что политики паролей соблюдаются.
- Рекомендовать использование централизованного управления ключами для production.
Тестировщик:
- Проверить поведение при повреждённых PDF.
- Проверить совместимость с разными версиями PyMuPDF.
Когда этот подход не подойдёт
- Если требуется юридически юридически обусловленная защита (требуются цифровые подписи и сертифицированные решения).
- Если нужно управлять ключами и аудитом на уровне предприятия — лучше использовать специализированный KMS и интеграцию с инфраструктурой.
Быстрый чек-лист внедрения
- Установить PyMuPDF в целевой окружение.
- Добавить обработку секретов (env / vault).
- Написать тесты: шифрование, расшифровка, ошибки.
- Протестировать на реальных корпоративных документах (без confidential данных в тестах).
Краткое резюме
Шифрование PDF в Python с PyMuPDF — удобный и относительно простой способ защитить содержимое документов. В статье приведён адаптивный код, учитывающий вариативность API, рекомендации по безопасности и набор тестов приёмки. Для производственных сценариев дополняйте решение управлением ключей и централизованной политикой паролей.
Дополнительные ресурсы: официальная документация PyMuPDF и утилита qpdf для командной строки.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента