Главная страница Статьи / Unix 101 прием работы с OpenSSL

Рекомендую - скидка 25%

Баннер

Поиск по сайту

Добавить в закладки!

odnaknopka.ru/kolyan.cz

101 прием работы с OpenSSL PDF Печать E-mail
Статьи - Unix

Весьма полезный документ, узнал из него полезные вещи такие как генерация парольных хэшей (ранее использовал perl-функцию crypt), что не всегда удобно

А вот генерировать ключи для apache гораздо проще в одну строку:

/usr/bin/openssl req -newkey rsa:1024 -nodes -keyout server.key -out server.crt -x509 -days 3650 -subj “/C=XX/ST=XX/L=XX/O=XX/OU=XX/CN=hostname.ru/emailAddress=” Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Название 101 прием работы с OpenSSL
Описание Забавы с OpenSSL
Автор Anton Karpov (toxa’at’real.xakep.ru)
Источник Хакер, номер #074

Забавы с OpenSSL

Все знают, что такое OpenSSL. По крайней мере, хотя бы по уязвимостям в mod_ssl для апача . Однако OpenSSL - это настоящий криптографический тулкит, который разве что кофе не варит. Рассказать здесь обо всех его возможностях - нереально, но я попытаюсь познакомить тебя с основными областями применения этой полезной утилиты.

Шифруем и подписываем

Самое простое, что может делать openssl - шифровать файлы, как симметричными алгоритмами (когда для шифрования и расшифровки нужна одна и та же парольная фраза), так и ассиметричными - с использованием rsa-ключей. Например, зашифруем файл симметричным алгоритмом des3 с помощью “openssl enc”:

# echo veryverysecretinfo > plain.txt
# openssl enc -des3 -e -in plain.txt -out enc.txt
enter des-ede3-cbc encryption password:
Verifying - enter des-ede3-cbc encryption password:

Можно убедиться, что enc.txt содержит нечитаемый текст. Расшифровать файл можно, заменив ключ “-e” ключом “-d”:

# openssl enc -des3 -d -in enc.txt -out plain.txt
enter des-ede3-cbc decryption password:

Чтобы получить шифртекст в base64-кодировке (ASCII-текст), используй ключ “-a”.

Т.к. openssl установлен практически на каждой машине, с его помощью можно быстро зашифровать информацию, которую необходимо передать по недоверенным каналам. Не знающие данной фишки хацкеры по-прежнему используют убогий zip с паролем, чтобы слить дамп базы через чужой приватный проксик . К этому можно добавить, что openssl поддерживает великое множество симметричных шифров, в том числе самые криптостойкие на сегодняшний день AES (алгоритм Rijndael) и IDEA. Вместо “-des3″ можно указать требуемый шифр.

Если же ты хочешь, чтобы собеседник передал тебе файл в зашифрованном виде, а ты его расшифровал, то стоит озаботиться ассиметричной криптографией, сгенерировав себе пару rsa-ключей, публичный и приватный, с помощью “openssl genrsa”:

# openssl genrsa -out rsaprivatekey.pem -des3 2048
Generating RSA private key, 2048 bit long modulus
……………..+++
…………….+++
e is 65537 (0×10001)
Enter pass phrase for rsaprivatekey.pem:
Verifying - Enter pass phrase for rsaprivatekey.pem:

Аргумент “-des3″ указывает, что приватный ключ следует защитить (зашифровать по алгоритму Triple DES) парольной фразой. При каждом использовании ключа тебе придется вводить эту фразу. Это безопасно, но часто неудобно, так что можешь опустить это параметр. Убедись, что на ключ проставлены права 600, чтобы никто в системе не мог прочитать твой ключ, да и вообще береги его, как зеницу ока. Получить соответствующий закрытому публичный ключ можно с помощью “openssl rsa”:

# openssl rsa -in rsaprivatekey.pem -pubout
-out rsapublickey.pem
Enter pass phrase for rsaprivatekey.pem:
writing RSA key
# cat rsapublickey.pem
—–BEGIN PUBLIC KEY—–
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4my4TOhq/X412X0UzKvK
kccra9Gq9+SDkBQGfI483obV+V2d054PnDyZ7uZghgVbrATc4hWTy26UPpdyxnBn
fGKiwtWjUlrMwEUZIQ4znTAcLey1Fc1TpbQchBtFaPe4UPNaLY1P/DxsHRXgI8mq
ctzdQVdd3TQkg/FV4hSvF3LOUfBHJOj7C7E4H8z7w+DN+c9lgo6v1J55KPovvaQo
HikfnixunYbOoIlD6V/vVoApjY4CeLomDECj4eE8w3B0oZdYeqq/iMkttCcK56p7
kymX8DpFItwFiDLvnwlN+oiKtyno+Ctf8yxwFNCNJNOXXE1IV4YAkY8ZO7Q3JhGp
MQIDAQAB
—–END PUBLIC KEY—–

Этот публичный ключ ты передаешь собеседнику, и он шифрует файл на нем, используя “openssl rsautl”:

# openssl rsautl -encrypt -pubin -inkey rsapublickey.pem
-in plain.txt -out cipher.txt

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

# openssl rsault -decrypt -inley rsaprivatekey.pem
-in cipher.txt -out plain.txt

Разумеется, знание твоего публичного ключа не поможет вскрыть шифртекст. Кроме шифрования, можно также подписывать файлы, предоставляя гарантии, что данный файл послан лично тобой, и давая возможность проверить его аутентичность. Делается это с помощью “openssl dgst”:

# openssl dgst -sha1 -sign rsaprivatekey.pem
-out sign.txt myfile.tar.gz

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

# openssl dgst -sha1 -verify rsapublickey.pem
-signature sign.txt myfile.tar.gz
Verified OK.

Если подпись не совпадает, ты получишь сообщение Verification Failure. Строго говоря, в предыдущем примере подписывался не файл, а message digest, или контрольная сумма файла. Она также может быть вычислена и без использования ключей. Тебе наверняка знакома утилита md5, которая высчитывает хэш файла (md5-сумму), позволяющий убедиться в его аутентичности. Если изменить в файле хотя бы бит, его md5-сумма полностью изменится. OpenSSL позволяет вычислять хэш, используя md5, sha, sha1, mdc2, и т.д. Во многих Linux-дистрибутивах утилита md5 отсутствует, но ты все равно можешь вычислить контрольную сумму, используя “openssl dgst”:

# openssl dgst -md5 myfile.tar.gz
MD5(myfile.tar.gz) =65b36f8d54b8bab0a787cbd4a8dd8aef

Еще с помощью OpenSSL можно быстро сгенерировать себе пароль, WEP-ключ и прочее, используя “openssl rand”:

# openssl rand -base64 45
0JZmfHQL3WI7PTUYcq1w8yQ8wFE3mB7Wd7vdAYd2A6×0cTHmVYqI/Su3o5qh

Если нужно найти соответствие пароля его шифру, например, если ты по какой-то причине решил напрямую править /etc/master.passwd (/etc/shadow), можно использовать “openssl passwd”:

# openssl passwd -1 mypassword
$1$OsmexMtO$0CtV.Lb6nhGOSGKM8jKNO.

Параметр “-1″ в данном случае указывает использование алгоритма md5 (им по умолчанию шифруются пароли во FreeBSD/NetBSD и многих дистрах линуха, в OpenBSD используется Blowfish).
Работаем с сертификатами

OpenSSL очень часто применяют именно для работы с цифровыми сертификатами. И немудрено, ведь в этом тулките есть все, чтобы построить свой маленький CA и выдавать сертификаты. Сейчас очень модно говорить о цифровых сертификатах и сертификационных (удостоверяющих) центрах. Что же это такое?

Обратись к началу статьи, где я рассказываю про ассиметричную криптографию и RSA-ключи. Для того чтобы N человек могли общаться между собой (например, подписывать и шифровать файлы), каждый должен иметь пару ключей - публичный и секретный - и каким-то образом (например, через персональную web-страничку) предоставить свой public key всем (N-1) людям. Очевидны две проблемы:

- Получать и хранить все (N-1) ключей, персонально запрашивая каждый у его владельца - весьма затруднительно. Да еще если учесть, что люди могут терять/раскрывать свои ключи и генерировать новые. Как я узнаю, что один из моих респондентов сгенерировал новый ключ, и старый уже не действителен?

- Как удостовериться, что публичный ключ собеседника принадлежит ему? Что его web-страничка с ключом не была взломана, а ключ - заменен?

Для решения этих проблем было решено ввести новый доверенный орган, который назвали Ceritifcate Authority, CA (русский официальный перевод - “удостоверяющий центр”), и теперь все участники, сгенерировав себе пару ключей (public-private), не ломают голову, а отправляют свой публичный ключ этому CA. Причем не в “голом виде”, а оформив его в запрос на сертификат - по сути, тот же ключ, с прописанными персонализирующими владельца ключа полями (имя, фамилия, город, адрес).

X509 - это стандарт на сертификаты. CA получает запрос и выдает автору ключа уже полноценный сертификат, одновременно удостоверяя авторство ключа, подписывая его своим private key и размещая сертификат клиента для публичного доступа. Таким образом, сертификат - тот же public key, только оформленный в специальном виде. Наконец, если кто-то теряет или раскрывает свой закрытый ключ, он создает CA запрос на отзыв сертификата (ceritificate revokation). CA помечает сертификат как отозванный, помещая информацию о нем в специальный список, CRL (ceritificate revokation list). Теперь, чтобы проверить, действителен ли ключ, нужно всего лишь скачать с сайта CA свежий CRL и проверить наличие в нем сертификата респондента.

Эта красивая схема содержит одно слабое звено - все участники обязаны безоговорочно доверять CA, ведь к нему они обращаются за ключами других людей, за CRL, да и сам CA непосредственно отвечает за то, что конкретный человек имеет данный ключ. Вот почему во всех странах функционирование официальных CA подведено под мощную юридическую базу, выпущены соответствующие законы. В России существует закон “Об Электронной Цифровой Подписи”, согласно которому юридическую силу имеют те CA, которые используют отечественные криптоалгоритмы (ГОСТ) для подписи и шифрования. “Имеют юридическую силу” - значит, подпись клиентом такого CA электронного документа (файла) на уровне закона приравнена к личной ручной подписи на бумаге. Впрочем, нам сгодится и RSA, мы же не ведем переписку государственной важности .

Для разворачивания полноценных CA существуют удобные фронтэнды, например, TinyCA. Нас, как всегда, интересует консольная подноготная всего процесса. Поэтому сейчас мы запустим свой маленький CA и выдадим на нем сертификат нашему веб-серверу. Генерируем rsa-ключ для CA:

# openssl genrsa -des3 -out myca.key 2048
# chmod 600 myca.key

Перед тем, как генерировать запросы и сертификаты, советую взглянуть на openssl.cnf (/etc/ssl/openssl.cnf), в котором прописаны поля сертификата, их обязательность и дефолтные значения. Можешь поменять их, чтобы было проще, или даже указать все значения прямо в запросе (ключ “-subj”). Выпустим сапоподписанный сертификат на сгенерированном ключе:

# openssl req -new -x509 -days 365 -key myca.key -out myca.crt

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

# openssl genrsa -out server.key 2048

Создадим запрос на сертификат (CSR, certificate sign request):

# openssl req -new -key server.key -out server.csr

Подпишем запрос на ключе CA и выдадим нашему серверу новый сертификат:

# openssl x509 -req -days 365 -CA myca.crt -CAkey
myca.key -in server.csr -out server.crt
# openssl verify -CAfile myca.crt server.crt

В процессе работы openssl ищет сертификат CA, CRL и некоторые другие параметры согласно файлу конфигурации /etc/ssl/openssl.cnf. Поэтому неплохо бы его заполнить, это избавит нас в том числе и от ввода параметров “-CA”, “-CAkey” и т.д. Так, если ты назвал свою CA MyCA и расположил иерархию каталогов в /etc/ssl, то внеси в конфиг:

# vi /etc/ssl/openssl.cnf

[ ca ]
default_ca = MyCA
[ MyCA ]
dir = /etc/ssl
certs = $dir/crt
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/crt_new
certificate = $dir/ca.crt
serial = $dir/serial
crl = $dir/myca.crl
private_key = $dir/myca.key

Теперь все будет складываться в /etc/ssl. Например, если мы хотим отозвать сертификат сервера по причине изменения его адреса:

# openssl ca -revoke server.crt -crl_reason affiliationChanged

Сгенерируем актуальный список отзыва (CRL):

# openssl ca -gencrl -out myca.crl

В index.txt должна появиться запись о смене статуса сертификата server.crt. Просмотреть же CRL можно следующей командой:

# openssl crl -in ca.crl -text -noout

Сам сертификат и его ключ можно просмотреть схожим образом:

# openssl x509 -in server.crt -noout -text
# openssl rsa -noout -text -in server.crt

Как настраивать Apache с mod_ssl, написано уже неоднократно, и я повторяться не буду. Но почему-то все ограничиваются банальной поддержкой https, а ведь с сертификатами можно натворить немало забавного. Например, создай папку ssl-area, к которой будут иметь доступ только те, у кого есть выданные тобой сертификаты. Для этого пропиши в конфиг ssl-хоста апача:

SSLRequireSSL
SSLVerifyClient require
SSLVerifyDepth 1

Наконец, важное замечание. Теоретически, сертификат - это открытый ключ. И некоторые программы (тот же Apache) разделяют понятия “сертификат” и “закрытый ключ” (и правильно), требуя указать в конфиге и то, и другое. Но некоторый софт, например, vsftpd, хочет найти в сертификате как публичный, так и закрытый ключ. Поэтому, если ты хочешь упростить себе жизнь, или столкнулся с тем, что какая-либо софтина не работает, помни, что ты просто можешь добавить secret key в конец сертификата (командой cat), хотя это, конечно, идеологически неверно.
Почта? SMIME!

В начале статьи мы зашифровывали файлы. А что, если их надо тут же из консоли отправить по почте? Можно, конечно, послать прямо ASCII-текст:

# cat ascii_encoded.txt | mail Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Но тогда получатель получит бессмысленный набор символов. Так что есть способ лучше - S/MIME. Это специальное расширение MIME (Multiple Internet Mail Extensions) для работы с сертификатами. Почтовые клиенты понимают SMIME и обрабатывают smime-вложения соответствующим образом (например, проверяют подпись). Сертификат у нас есть, подпишем им сообщение:

# openssl smime -sign -signer server.crt -inkey
server.key -in message.txt -text | mail Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

А теперь еще зашифруем:

# openssl smime -encrypt -in message.txt -signer
server.crt -inkey server.key -text | openssl smime -encrypt
-des3 myserver.crt -out mail.msg | mail Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript

Очень часто бывает нужно протестировать работу сетевого сервиса. Обычно для этого применяют telnet. Но если сервис работает через SSL? Тогда нас снова спасет openssl:

# openssl s_client -connect myserver:443

Твоему взору предстанет сертификат сервера, проверки, а затем ты увидишь привычный баннер сервера и сможешь передавать команды.
Outro

Т.к. OpenSSL - комплексный и сложный тулкит, его man-страницы нельзя назвать идеальными. Все возможности (ca, smime, rsa, etc) раскиданы по разным файлам. В рамках проекта OpenBSD, славящегося своей отменной документацией, написан свой man openssl: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.sbin/openssl/openssl.1. Превратить его в текстовый файл можно с помощью groff:

# groff -man -Tascii openssl.1 > openssl.1.man

Собственно, ничего полезнее тебе напоследок порекомендовать не могу, кроме как внимательно изучить этот документ.
WWW

www.openssl.org
www.openbsd.org
www.stunnel.org
www.opensslbook.com
www2.psy.uq.edu.au/~ftp/Crypto/

 
Документация @ Ihtiandr.Info