×
Главная   »   Статьи   »   Шифрование файлов в Linux: GPG, openSSL и модуль cryptography
Шифрование файлов в Linux: GPG, openSSL и модуль cryptography
Метки:      ,   ,   ,   ,   

В этой статье научимся использовать симметричное и ассиметричное шифрование. Познакомимся с утилитами GPG и openSSL и напишем свою программу на Python для шифрования текстового файла.

Автор статьи никого не призывает к правонарушениям и отказывается нести ответственность за ваши действия. Вся информация предоставлена исключительно в ознакомительных целях. Все действия происходят на виртуальных машинах и внутри локальной сети автора. Спасибо!

Сегодня мы не будем разбираться в алгоритмах шифрования, а выясним, как шифровать на практике. Начнем с симметричного шифрования, в котором для шифрования и дешифрования используется один и тот же ключ. После чего рассмотрим ассиметричное шифрование при помощи утилиты GPG. Далее очень поверхностно научимся использовать openSSL для генерации пары открытый/закрытый ключ, которые применим для шифрования/расшифрования текстового файла при помощи Python.

Симметричное шифрование при помощи GPG

Создайте любой текстовый файл и заполните любыми данными.

cat > answer

Теперь вы можете его зашифровать при помощи команды gpg. Для шифрования выполните следующую команду:

gpg -c answer  

Будет создан файл с тем же именем и расширением .gpg. Можете более подробно узнать о файле при помощи команды file answer.gpg:

answer.gpg: GPG symmetrically encrypted data (AES256 cipher)

Чтобы расшифровать наш файл, используйте ключ -d:

gpg -d answer.gpg

После чего у вас будет запрошен «фраза-пароль» и вы увидите содержимое файла. Для большего понимания запустите еще раз команду дешифрования. Файл расшифровался и gpg даже не запросила пароль?

По большому счету, gpg использует ключ по умолчанию на вашем компьютере в качестве ключа шифрования/дешифрования, а кодовая фраза предназначена для обеспечения работы дешифрования с другими машинами. По сути, он тайно создает и сохраняет реальный ключ шифрования, а затем шифрует его с помощью ключевой фразы и объединяет зашифрованный ключ и зашифрованный открытый текст в выходные данные. Когда сессия закончится, необходимо будет снова ввести фразу-пароль, чтобы получить доступ к хранилищу ключей. Про добавление и удаление ключей GPG написано немного на этой странице и очень подробно написано здесь.

Ассиметричное шифрование при помощи GPG

Чтобы создать ключ наберите следующую команду:

gpg --full-gen-key

Необходимо будет выбрать тип ключа, его размер, срок действия ключа (0 – бессрочно), реальное имя, email и комментарий, при необходимости. В конце подтвердить введенные данные и придумать фразу-пароль. В консоль будет выведен публичный ключ.

Доступные ключи можно увидеть с помощью команды gpg --list-keys. Сами ключи хранятся в следующей директории:

/root/.gnupg

Приступим к шифрованию, необходимо будет указать идентификатор (имя, которое вы указывали при создании ключа) и сам файл, который шифруем:

gpg -e -r идентификатор_пользователя название_файла

Расшифровываем также, как в предыдущем случае.

gpg -d answer.gpg

Экспортировать открытый ключ можно следующей командой:

gpg --export -a "идентификатор_пользователя" > public.key

А закрытый, такой:

gpg --export-secret-keys -a "идентификатор_пользователя" > private.key

Теперь переходим к программированию. Разберемся как работают программы-вымогатели.

Криптографическая библиотека openSSL

К библиотеке openSSL мы еще вернемся, а пока давайте кратко разберемся, как создать новую пару ключей. Чтобы сгенерировать новый RSA-ключ длиной 4096, введите следующую команду:

openssl genrsa -out my_key.key 4096

Чтобы вывести эти ключи, используйте следующую команду:

openssl rsa -text -in my_key.key

Теперь давайте извлечем только открытый ключ, который нам в дальнейшем пригодится.

openssl rsa -in my_key.key -pubout -out public_key.key

Перейдем к написанию программы для шифрования файлов на Python.

Программа для шифрования файлов на Python

Для написания программы будем использовать модуль cryptography. Реализуем программу с таким синтаксисом:

python3 script.py –e путь_до_открытого_ключа путь_до_файла
python3 script.py -d путь_до_закрытого_ключа путь_до_файла

В первом случае мы будем шифровать текстовый файл и сохранять результат в этом же файле. Во втором случае расшифруем его. Для начала импортируем все необходимое.

import sys
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

Напишем тело программы и перейдем к самому интересному, функциям encrypt() и decrypt():

if __name__ == '__main__':
    mode = sys.argv[1]
    path_key = sys.argv[2]
    path_file = sys.argv[3]

    if mode == '-e':
        encrypt(path_key, path_file)
    elif mode == '-d':
        decrypt(path_key, path_file)

Найдем в документации cryptography функцию для работы с открытым ключом. Воспользуемся функцией load_pem_public_key(), которая сама определяет тип ключа по заголовку -----BEGIN {FORMAT} ----- в один из поддерживаемых типов асимметричных открытых ключей.

def encrypt(path_public_key, path_file):
    with open(path_public_key, 'rb') as key_file:
        public_key = serialization.load_pem_public_key(
            key_file.read()
        )
    with open(path_file, 'rb') as file:
        file_data = file.read()

Мы открываем открытый ключ при помощи функции load_pem_public_key() и сохраняем в переменную public_key.  Далее открываем файл, который будем шифровать этим ключом. Если вас интересует, почему мы не указывали аргумент backend, то вам сюда. Для начала разберемся, что сохранилось в переменную public_key:

<cryptography.hazmat.backends.openssl.rsa._RSAPublicKey object at 0x7fb792c42ee0>

Найдем в документации класс RSAPublicKey и посмотрим его методы. Метод encrypt – то что нужно. Первым параметром указывается текст, который нужно зашифровать, вторым – padding.

Для шифрования будем использовать схему OAEP, которая зарекомендовала себя достаточно надежной. Найдем ее в документации.

…
    encrypted_data = public_key.encrypt(
        file_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

Осталось только записать зашифрованный текст в тот же файл:

…
    with open(path_file, 'wb') as file:
        file.write(encrypted_data)

Функция для расшифровки аналогична, только используется закрытый ключ. Полный код:

import sys
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes

def encrypt(path_public_key, path_file):
    with open(path_public_key, 'rb') as key_file:
        public_key = serialization.load_pem_public_key(
            key_file.read()
        )

    with open(path_file, 'rb') as file:
        file_data = file.read()

    encrypted_data = public_key.encrypt(
        file_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    with open(path_file, 'wb') as file:
        file.write(encrypted_data)

def decrypt(path_private_key, path_file):
    with open(path_private_key, 'rb') as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(),
            password=None
        )

    with open(path_file, 'rb') as file:
        file_data = file.read()

    encrypted_data = private_key.decrypt(
        file_data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )

    with open(path_file, 'wb') as file:
        file.write(encrypted_data)

if __name__ == '__main__':
    mode = sys.argv[1]
    path_key = sys.argv[2]
    path_file = sys.argv[3]

    if mode == '-e':
        encrypt(path_key, path_file)
    elif mode == '-d':
        decrypt(path_key, path_file) 

В этой статье мы научились использовать утилиту GPG для симметричного и асимметричного шифрования. Очень кратко рассмотрели openSSL и самостоятельно реализовали программу на Python с модулем cryptography для шифрования/расшифрования текстового файла с использованием открытого/закрытого ключа.

1028 просмотров
09.03.2023
Автор