Pull to refresh

OpenSSL: простое шифрование с открытым ключом

Reading time3 min
Views70K
Полно ситуаций когда нужно зашифровать определённый файл или папку. Например, если данные передаются по открытым каналам либо сохраняются на внешнем носителе. Многие (в том числе и я) используют truecrypt, однако основное предназначение этой программы — работа с зашифрованными разделами, поэтому она не очень хороша в этом случае.

Для подобных задач вполне подходит OpenSSL — надёжное кросплатформенное решение. OpenSSL поддерживает различные алгоритмы шифрования, плюс он по умолчанию установлен во многих операционных системах, а установка на остальные не составит труда.

Под хабракатом — основы использования симметричного и асимметричного шифрования в OpenSSL, а таке пара скриптов упрощающих асимметричное шифрование с одноразовым ключом.

Простейший способ защиты данных с помощью OpenSSL — симметричное шифрование. Следующие команды шифруют и расшифровывают файл documents.zip, используя алгоритм AES с длиной ключа 256 бит:

openssl enc -aes-256-cbc -salt -in documents.zip -out documents.enc
openssl enc -d -aes-256-cbc -in documents.enc -out documents.zip


Проблема этих команд может заключаться в том что они требуют ввода пароля. Есть ситуации когда это нежелательно. Например, автоматическое резервное копирование/шифрование данных по расписанию, либо если данные шифруются одним человеком а расшифровываются другим.

Как раз для таких случаев было придумано шифрование с открытым ключом. В общем случае вам понадобится создать открытый и закрытый ключи. Первая команда сгенерирует закрытый ключ private.pem, вторая создаст открытый ключ public.pem:

openssl genrsa -out private.pem -aes256 2048
openssl rsa -in private.pem -pubout -out public.pem


В результате вы получаете пару RSA ключей длиной 2048 бит. К сожалению, в системе RSA размер шифруемых данных ограничен размером ключа, поэтому зашифровать более 2Кб данных не получится. Есть способ обойти это — информация сначала шифруется симметричным алгоритмом (подобно использованному выше) с использованием одноразового ключа. Затем этот одноразовый ключ шифруется публичным ключом. При расшифровке одноразовый ключ расшифровывается закрытым. Подробнее об этом уже было очень хорошо написано в статье на Хабре.

Автоматизировать шифрование поможет следующий скрипт, на выходе которого вы получите одноразовый ключ и данные (encrypt.sh) в зашифрованном виде:

# !/bin/bash

FILENAME="$1"
PUBLICKEY="$2"
SESSIONKEY="$3"
RESULT="$4"

# Generate the random symmetric-key
PASSIZE=30
if [ -c /dev/urandom ] ; then
KEY=`head -c 30 /dev/urandom | openssl enc -base64`
else
KEY=`openssl rand -base64 30`
fi
export KEY

# Encrypt the symmetric key using the public key
openssl rsautl -encrypt -inkey "$PUBLICKEY" -out "$SESSIONKEY" -pubin <<EOF
$KEY
EOF

# Encrypt the file
openssl enc -aes-256-cbc -pass env:KEY -in "$FILENAME" -out "$RESULT"


Следующая команда использует открытый ключ public.pem чтобы зашифровать файл documents.zip. Она сгенерирует зашифрованный одноразовый ключ session.key и зашифрованные данные documents.enc:

./encrypt.sh documents.zip public.pem session.key documents.enc

Скрипт для дешифрования (decrypt.sh):

# !/bin/bash

PRIVATEKEY="$1"
SESSIONKEY="$2"
ENCRYPTED="$3"
DECRYPTED="$4"

# Decrypt the symmetric key using the private key
KEY=` openssl rsautl -decrypt -inkey "$PRIVATEKEY" -in "$SESSIONKEY" `
export KEY

# Decrypt the file
openssl enc -aes-256-cbc -d -pass env:KEY -in "$ENCRYPTED" -out "$DECRYPTED"


Команда для дешифрования использует закрытый ключ private.pem и одноразовый ключ session.key чтобы расшифровать файл documents.enc. Она сгенерирует файл documents.zip:

./decrypt.sh private.pem session.key documents.enc documents.zip

Как видите, шифрование с открытым ключом может быть почти таким же простым как и симметричное. Но есть ещё более простой путь. На написание этого поста меня побудил блог SbF₅. Его автор (несомненно более искушённый в bash чем я) написал скрипт, который архивирует папку, шифрует её открытым ключом и генерирует другой скрипт, содержащий в себе всё необходимое: одноразовый ключ, данные и собственно команды для расшифровывания. Кроме того, скрипт может сгенерировать для вас пару RSA ключей:

./encrypt-file.sh -keys public.pem private.pem
./encrypt-file.sh folder public.pem > decrypt-folder.sh
chmod +x decrypt-folder.sh
./decrypt-folder.sh private.pem > folder.tar


В этом примере мы сначала сгенерировали пару ключей. После этого папка folder была зашифрована в скрипт decrypt-folder.sh а затем расшифрована в архив folder.tar. Возможный минус этого способа — то что данные в decrypt-folder.sh хранятся в формате BASE64, а следовательно их размер увеличивается.

Вот, собственно, то, чем я хотел поделиться. Если у кого-то есть замечания или вопросы — пишите в комментарии, постараюсь ответить.

UPD Перенесено в блог Информационная безопасность.
Tags:
Hubs:
+9
Comments1

Articles