Одним из ключевых инструментов, предоставляющих возможность обеспечения безопасности, является криптография. В статье рассмотрим использование библиотеки Cryptography Python для шифрования и дешифрования данных.
Еще по теме: Обфускация Python с помощью Pyarmor
Симметричное шифрование Python
В отличие от некоторых других языков программирования, в Python отсутствуют встроенные средства для шифрования. Несколько библиотек с открытым кодом восполняют этот пробел. Самыми популярными пакетами для криптографии являются Cryptography и Pycryptodome.
В наших статьях часто используется именно Cryptography, так как в нем меньше возможностей «выстрелить себе в ногу».
Симметричное шифрование с помощью Cryptography
Cryptography — это библиотека Python для обеспечения криптографических функций. Библиотека предоставляет разнообразные инструменты и алгоритмы для выполнения шифрования, дешифрования, создания хешей сообщений и генерации ключей. Она является надежным решением для реализации различных методов шифрования, начиная от симметричного и асимметричного шифрования, и заканчивая созданием цифровых подписей и хешей.
Возможности Cryptography:
- Симметричное шифрование (AES, Camellia, Blowfish и др.) — позволяет зашифровать и расшифровать данные с использованием одного ключа.
- Асимметричное шифрование (RSA, ECC и др.) — использует публичный и приватный ключи для шифрования и подписи сообщений.
- Генерация ключей и ключевых пар для разных алгоритмов.
- Работа с сертификатами X.509.
- Вычисление и проверка цифровых подписей и хешей.
- Управление процессом шифрования (режимы работы, векторы инициализации).
- Интеграция с системами управления ключами и хранилищами сертификатов.
- Поддержка стандартов шифрования как для веб (TLS, SSL), так и для других протоколов.
По умолчанию за кулисами пакета трудится библиотека OpenSSL, имеющая открытый код. В ней реализованы сетевые протоколы, отвечающие за безопасность, и криптографические функции для широкого круга задач. В основном библиотека написана на C. Она также находится под капотом множества других библиотек для всевозможных языков программирования.
Авторы пакета разделили доступные в нем возможности на две категории:
- «взрывчатые вещества», нетривиальные низкоуровневые инструменты;
- «готовые рецепты», высокоуровневые и несложные в использовании.
Большинству программистов на Python для шифрования будет достаточно готовых рецептов.
Шифрование с помощью AES Cryptography Python
Библиотека Cryptography Python доступна в репозитории PyPI. Для установки выполните команду:
1 |
$ pip install cryptography |
Основное преимущество Cryptography по сравнению с другими библиотеками криптографии, такими как Pycryptodome, заключается в том, что она обеспечивает отличную производительность при выполнении криптографических операций.
Симметричное шифрование с помощью Fernet Cryptography Python
Один из готовых рецептов реализует метод симметричного шифрования под названием fernet. Его нормативная документация описывает протокол для шифрованного взаимодействия, стойкий к постороннему вмешательству. Его воплощает класс Fernet, который находится в cryptography.fernet.
В классе Fernet есть все, что вам, как правило, потребуется для шифрования данных. Метод Fernet.generate_key создает ключ длиной 32 случайных байта, который требуется конструктору класса в качестве аргумента.
Под капотом Fernet делит переданный ключ на два 128-битных. Один используется для шифрования, а второй – для проверки подлинности.
Метод Fernet.encrypt не только шифрует открытый текст, он также высчитывает хеш от шифротекста функцией HMAC-SHA256. То есть шифротекст для хеш-функции является сообщением. Шифрованный текст и хеш возвращаются внутри объекта под названием fernet token.
Fernet представляет собой реализацию симметричного шифрования и гарантирует, что зашифрованное сообщение нельзя изменить или прочитать без ключа. Дополнительную информацию о данном классе можно найти в официальной документации.
Для генерации ключа можно использовать метод generate_key() из интерфейса Fernet. Следующий код использует функции пакета Cryptography для шифрования строки на Python.
1 2 3 4 5 6 7 8 9 10 11 12 |
from cryptography.fernet import Fernet key = Fernet.generate_key() cipher_suite = Fernet(key) print("Ключ: " + str(cipher_suite)) message = "Secret message".encode("utf8") cipher_text = cipher_suite.encrypt(message) plain_text = cipher_suite.decrypt(cipher_text) print("Cipher text: " + str(cipher_text.decode())) print("Plain tex: " + str(plain_text.decode())) |
В коде мы импортируем Fernet из cryptography.fernet. Затем генерируем ключ шифрования, который будет использоваться как для шифрования, так и для дешифрования. Класс Fernet создается с ключом шифрования, и строка шифруется путем создания экземпляра этого класса. Она расшифровывается с использованием экземпляра класса Fernet.
Можно улучшить предыдущий скрипт, добавив возможность сохранения ключа в файле, чтобы использовать его как для функций шифрования, так и для функций расшифровки. Для этой задачи нам нужно импортировать класс Fernet и начать генерировать ключ, который необходим для симметричного шифрования/расшифровки.
1 2 3 4 5 6 7 8 9 |
from cryptography.fernet import Fernet def generate_key(): key = Fernet.generate_key() with open("secret.key", "wb") as key_file: key_file.write(key) def load_key(): return open("secret.key", "rb").read() |
В коде мы определяем функцию generate_key(), которая генерирует ключ и сохраняет его в файл secret.key. Вторая функция, load_key(), считывает ранее сгенерированный ключ из файла secret.key:
1 2 3 4 5 6 |
def encrypt_message(message): key = load_key() encoded_message = message.encode() fernet = Fernet(key) encrypted_message = fernet.encrypt(encoded_message) return encrypted_message |
В коде мы определяем функцию encrypt_message(), которая шифрует переданное в параметре сообщение, используя объект Fernet и метод encrypt() этого объекта.
Вторая функция расшифровывает зашифрованное сообщение. Для расшифровки сообщения просто вызываем метод decrypt() из объекта Fernet.
1 2 3 4 5 |
def decrypt_message(encrypted_message): key = load_key() fernet = Fernet(key) decrypted_message = fernet.decrypt(encrypted_message) return decrypted_message.decode() |
Основная программа просто вызывает предыдущие функции с жестко заданным сообщением для тестирования методов шифрования и расшифровки.
1 2 3 4 5 |
if __name__ == "__main__": generate_key() message_encrypted = encrypt_message("зашифровать это сообщение") print('Message encrypted:', message_encrypted) print('Message decrypted:', decrypt_message(message_encrypted)) |
Можно использовать ранее сгенерированный файл secret.key для шифрования содержимого файла с именем file.txt в файл file_encrypted.txt. Используя тот же ключ, можно расшифровать содержимое этого файла.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
from cryptography.fernet import Fernet import os def load_key(): return open("secret.key", "rb").read() def encrypt_file(file, key): fernet = Fernet(key) with open(file, "rb") as myfile: file_data = myfile.read() data = fernet.encrypt(file_data) print("Data encrypted:", data.decode()) with open("file_encrypted.txt", "wb") as file: file.write(data) def decrypt_file(file_encrypted, key): fernet = Fernet(key) with open(file_encrypted, "rb") as myfile: file_data = myfile.read() data = fernet.decrypt(file_data) print("Data decrypted:", data.decode()) if __name__ == '__main__': file = 'file.txt' file_encrypted = 'file_encrypted.txt' key = load_key() encrypt_file(file, key) decrypt_file(file_encrypted, key) |
При выполнении предыдущего скрипта можно увидеть, как создается новый файл с зашифрованным содержимым из file.txt.
Заключение
Библиотека Cryptography Python предоставляет инструменты для реализации криптографической безопасности в ваших приложениях. Она позволяет легко выполнять шифрование, дешифрование и другие криптографические операции с минимальными усилиями.
Еще одним способом использования Fernet является передача ключа в конструктор параметра init. Этот ключ может быть получен из пароля с помощью алгоритма PBKDF2, который предоставляет функциональность для генерации пароля через функцию производства ключей.
ПОЛЕЗНЫЕ ССЫЛКИ:
- Асимметричное шифрование Python
- Шифрование и дешифрование в PowerShell
- Взлом пароля Windows используя обратимое шифрование