[Из песочницы] Ещё раз об OpenSSL

Habrahabr 1

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

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

Создадим приватный ключ командой.

openssl genrsa -out key.pem -aes-256-cfb -rand /var/log/messages 4096

Здесь:

genrsa — парметр указывающий на создание ключа алгоритмом шифрования RSA. out — где создать ключ. 4096 — длина ключа. Вообще этого для создания ключа достаточно. Но приватный ключ лучше зашифровать. aes-256-cfb — алгоритм и режим шифрования. rand /var/log/messages — рандомное значения из любой папки, лучше взять логи, т.к. с /dev/random или /dev/urandom может все повиснуть наглухо, у меня так и было. При создании ключа будет запрошен пароль. Пароль — это основа любой защиты, так что постарайтесь покорпеть над ним. И запомнить. Имеем ключ. Приватный. Никому никогда не показывать и спрятать по принципу Кощея Бессмертного.

На его основе сделаем публичный, который можно хоть на всеобщее обозрение выложить, хоть на лоб приклеить.

openssl rsa -in privatkey.pem -pubout -out publickey.pem

Теперь у нас есть пара ключей. Публичный можно закинуть на сервер, чтобы подключаться к нему по ssh, используя свой приватный ключ. Либо для шифрования небольшого количества данных, например, токена или парольной фразы и т.п.

Задача шифрования большого файла имеет другое решение.

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

Большой объем данных шифруется симметричным алгоритмом шифрования, например, AES. Здесь мы применим и асимметричное шифрование для передачи симметричного ключа, с помощью которого мы и будем шифровать текст.

Начнем.

Создадим симметричный сессионный (одноразовый) ключ рандомной последовательностью символов и запишем в файл в представлении base64.

openssl rand -base64 32 > key.bin
Далее зашифруем файл этим ключом:
openssl enc -aes-256-cfb -salt -in OWASP_Top_10-2017_\(en\).pdf -out OWASP_Top_10-2017_\(en\).pdf.enc -pass file:./key.bin

aes-256-cfb — алгоритм и режим шифрования. О режимах здесь не буду говорить. Этот лучший. salt — соль для большей криптостойкости. pass file:./key.bin — ключ шифрования.

Далее зашифруем симметричный ключ нашим публичным «ассиметричным» ключом.

openssl rsautl -encrypt -inkey publickey.pem -pubin -in key.bin -out key.bin.enc

Получили зашифрованный файл и симметричный ключ. Можно слать своему товарищу для расшифровки. Но мы пошлем сами себе, ибо это homework c самим с собой.

Теперь удалим изначальный симметричный ключ! Чтобы никто и никогда не нашел его.

shred -u key.bin
На картинке внизу его уже нет.

Теперь расшифруем симметричный ключ нашим приватным ассиметричным ключом.

openssl rsautl -decrypt -inkey privatkey.pem -in key.bin.enc -out key.bin
И мы, счастливчики, снова имеем симметричный ключ для расшифрования нашего текста, пока еще зашифрованного.

Картинка снова внизу, там ключ вновь есть.

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

openssl enc -d -aes-256-cfb -in OWASP_Top_10-2017_\(en\).pdf.enc -out OWASP_Top_10-2017_\(en\)decrypt.pdf -pass file:./key.bin
Пруф внизу.

Теперь: Почему так сложно? Почему нельзя взять и сделать все с помощью ассиметричного шифрования?

Пробуем, идем прямиком на грабли;) Имеем!

Файл и ключи.

Шифруем.

openssl rsautl -encrypt -inkey publickey.pem -pubin -in OWASP_Top_10-2017_\(en\).pdf -out OWASP_Top_10-2017_\(en\).pdf.enc
Поу — поу — поооооууууу. Ошибка. Слишком много данных для размера ключа. Ибо в ассиметричном шифровании размер ключа должен быть больше или равен открытому тексту. OpenSSL, как при сделке с дьяволом, дал Вам то, чего Вы попросили, но не чего хотели. Правда, зашифрованный файл оказался пуст.

Но можно зашифровать меньший, чем ключ файл. Попробуем.

Создадим небольшой файл.

Например, я сделал так:

echo "hellow world my name is admin is a secret text nobody know it hahahahaahah" > text.txt

Зашифруем его нашим публичным ключом, который знают все на свете!

openssl rsautl -encrypt -inkey publickey.pem -pubin -in text.txt -out text.txt.enc
Как видим на нижней картинке файл зашифрован. Ничего не понятно! Кому понятно, КТО ВЫ?

Теперь расшифруем, предварительно удалив для чистоты эксперимента исходный файл.

openssl rsautl -decrypt -inkey privatkey.pem -in text.txt.enc -out text.txt

Имеем расшифрованный файл. Все отлично.

Для передачи всего этого зашифрованного добра лучше последнее кодировать в base64. Соответственно перед тем как расшифровать, нужно сначала раскодировать. Закодировали.

openssl enc -base64 -in text.txt.enc -out text.txt.bs64

Раскодировали.

openssl enc -base64 -d -in text.txt.bs64 -out text.txt.enc

И снова имеем белеберду, которая никому не понятна! Если Вам понятна, то этот документ не для Вас!

Примерно так работает шифрование при создании ключей и шифрованиие данных на примере утилиты OpenSSL.

Позже собираюсь описать режимы шифрования блочных симметричных шифров.