OpenSSl

История

В 1988 году Международный союз электросвязи (International Telecommunication Union - ITU) опубликовал рекомендации по методам аутенификации в протоколе доступа к службе каталогов (Direcrotry access protocol - DAP). Все рекомендации союза по компьютерным сетям (реализация модели ISO/OSI) маркировались буквой "X" и номером. Серия посвященная службе каталогов получила номера с X.500 и далее. Система аутенификации на основе публичных ключей и сертификатов получила название X.509. В дальнейшем, часть рекомендаций X.500 была реализована в протоколе LDAP, а фреймворк предложенный в X.509 была использована в вебе для реализации протокола SSL и связанной с ним иерархией отношений доверия (RFC 5280).

В частности, X.509 ввёл понятия:

  • сертификат пользователя (сертификат): открытые ключи пользователя вместе с другой вспомогательной информацией, подписанные с помощью секретного ключа, выдавшего его органа по сертификации;
  • центр сертификации (certification authority - CA): орган, которому пользователи доверяют создание и подпись сертификатов. Опционально центр сертификации может создавать и ключи пользователя;
  • путь сертификации: упорядоченная последовательность сертификатов объекта, которая вместе с публичным ключом начального объекта в пути, может быть использована для проверки публичного ключа конечного объекта в пути;
  • доверие: ключевая роль доверия в структуре аутентификации заключается в отношениях между объектом аутентификации и центром сертификации; аутентифицирующий должна быть уверен, что центр сертификации создаёт только действительные и надежные сертификаты.

Для реализации стандарта X.509 и связанных с ним стандартов (алгоритмы шифрования, форматы хранения даннных и т.п.) была разработана библиотека OpenSSL, которая поставляется с утилитой командной строки openssl, и позволяет выполнять все основные криптографические операции. Библиотека Openssl реализована для всех основных ОС, в том числе Linux, Windows, Mac OS, Android и т.д.

Манипуляции с сертификатами

Для корректной работы многих сервисов в современном интернете требуется наличие сертификатов. В качестве примера можно привести HTTPS, SMTP поверх TLS, OpenVPN. В зависимости от сферы применения к сертификатам предъявляются разные требования:

Веб сервер с поддержкой SSL (HTTPS). Необходим серверный сертификат подписанный официальным удостоверяющим центром, сертификат которого есть в поставке популярных браузеров.

Почтовый сервер с поддержкой SSL (SMTP поверх TLS, POP3S, IMAPS). Для SMTP обычно достаточно самоподписанного серверного сертификата. Для POP3S, IMAPS желательно иметь официальный сертификат, поскольку почтовые клиенты (например Thunderbird) выдают предупреждения о неизвестных или некорректных сертификатах.

С OpenVPN поставляется собственный удостоверяющий центр, который позволяет создавать сертификаты сервера и клиента. Сертификат этого центра генерируется локально и добавляется в файл конфигурации клиента и сервера.

LetsEncrypt

Проект LetsEncrypt направлен на массовое внедрение HTTPS в интернете. Он предоставляет бесплатный удостоверяющий центр и наборы скриптов (для разных ОС разные), которые автоматически генерируют пару ключей, создают запрос на выпуск сертификата, отправляют его в удостоверяющий центр LetsEncrypt, а затем автоматически добавляют полученный сертификат в настройки популярных веб-серверов (Apache,Nginx, IIS).

Для почтового сервера достаточно прописать путь к файлу сертификата LetsEncrypt и использовать его совместно с веб-сервером.

EasyRSA

Вместе с OpenVPN поставляется набор скриптов easyrsa (есть под Linux и Windows), которые вызывают openssl для выполнения основных манипуляций с сертификатами. В набор скриптов входят:

  • build-ca - создать приватный ключ удостоверяющего центра (CA)
  • build-key-server - создать серверный приватный ключ и сертификат, подписанный ключом CA
  • build-dh - создать серверный ключ Диффи-Хелмана
  • build-key - создать клиентский приватный ключ и сертификат, подписанный ключом CA
  • build-key-pkcs12 - создать приватный ключ, сертификат и упаковать их вместе сертификатом CA

Версии с добавлением -pass потребуют ввода пароля для шифрования приватного ключа.

В файле openssl.cnf хранятся различные параметры openssl. Многие из них ссылаются переменные окружения, поэтому реальные настройки находятся в файле vars.sh (vars.bat).

vars.sh (фрагмент)

export KEY_SIZE=1024
export CA_EXPIRE=3650
export KEY_EXPIRE=3650

# Атрибуты сертификата
# могут быть изменены в диалоговом режиме
# при создании сертификата
export KEY_COUNTRY="RU"
export KEY_PROVINCE="EKB"
export KEY_CITY="Ekaterinburg"
export KEY_ORG="IMM"
export KEY_EMAIL=""

EasyRSA в подробностях

Внутри скриптов EasyRSA находятся вызовы openssl. Следует помнить, что часть параметров, такие как тип и размер ключа, ключ CA и т.п. находятся в файлt openssl.cnf.

Создание ключа CA без сертификата

 #запрос на сертификат сроком на 10 лет
 openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.csr -config openssl.cnf

Создание пары ключ-сертификат клиента

 #запрос на сертификат сроком на 10 лет
 openssl req -days 3650 -nodes -new -keyout client.key -out client.csr -config openssl.cnf
 #подпись сертификата ключом CA
 openssl ca -days 3650 -out client.crt -in client.csr -config openssl.cnf

то же для сервера

 #запрос на сертификат сроком на 10 лет
 openssl req -days 3650 -nodes -new -keyout srv.key -out srv.csr -config openssl.cnf
 #подпись сертификата ключом CA
 openssl ca -days 3650 -extensions server -in srv.csr -out srv.crt -config openssl.cnf

Экспорт в формат PKCS#12

 #запрос на сертификат сроком на 10 лет
 openssl req -days 3650 -nodes -new -keyout client.key -out client.csr -config openssl.cnf
 #подпись сертификата ключом CA
 openssl ca -days 3650 -in client.csr -out client.crt -config openssl.cnf
 # конвертация пары ключ/сертификат в файл pkcs#12.
 openssl pkcs12 -export -inkeyclient.key -in client.crt -certfile ca.crt -out client.p12

Формат сертификатов

Формальное описание структур данных

Стандарт X.509 предполагает, что все структуры данных, связанные с сертификатами описываются в формате ASN.1. ASN.1 - это архитектурно-независимое представление данных, пригодное для хранения произвольных иерархических структур. На практике, структура ASN.1 кодируется в двоичное представление DER (Distinguished Encoding Rules), описанное в X.690.

Все объектов в ASN.1 имеют уникальные идентификаторы OID (Object Identifier), для которых определены базовые типы данных (числа, строки, коллекции и т.п). OID - это последовательность положительных целых чисел, однозначно идентифицирующая объект. В текстовой записи OID выглядит как десятичные числа, разделяемые точкой - 1.2.345.6.79. Структура OID описывает дерево, корень которого расположен в начале записи. При записи в человекочитаемой форме корневой OID заменяют на некую мнемоническую строку, которую продолжают числовой последовательностью. Например корневой OID ветки, описывающей объекты алгоритма RSA, выглядит так: 1.2.840.113549.1. На специализированном сайте можно выяснить, что это: {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)}. Российский сегмент OID {iso(1) member-body(2) ru(643)} по соглашению с Росстандартом обслуживает ОАО "Инфотекс Интернет Траст". Объекты, связанные с российской криптографией, находятся в ветке 1.2.643.100 и описаны в Приказе ФСБ РФ от 27 декабря 2011 г. N 795 "Об утверждении Требований к форме квалифицированного сертификата ключа проверки электронной подписи".

Для обеспечения уникальности, те или иные OIDы регистрируются некими официальными организациями при координации ISO и ITU. К таким регистрирующим организациям относится IANA, которая выделяет OIDы, необходимые для протоколов сети Интернет (например, LDAP и SNMP). Частная организация может получить стартовый OID, и строить от него поддерево для внутреннего использования. В России регистрацией частных OID занимается ОАО "Инфотекс Интернет Траст".

Просмотр ASN.1 структуры ключа:

openssl asn1parse -in x509-key.pem

Типы сертификатов

  • RFC 5280 описывает формат сертификата X.509 (расширение файла .crt,.cer, .der, .pem) и списка отозванных сертификатов (.clr)

Кроме того, серия документов Public-Key Cryptography Standards (PKCS), созданная корпорацией RSA, описывает различные типы сертификатов X.509. Документы имеют порядковую нумерацию, записанную через #.

  • PKCS #1 (RFC 8017) описывает алгоритм RSA и формат его ключей
  • PKCS #7 (RFC 2315) описывает формат криптографического сообщения (зашифрованного и/или подписанного) (.p7b)
  • PKCS #8 (RFC 5208) описывает формат приватного ключа (.key)
  • PKCS #10 (RFC 2986 ) описывает формат запроса на сертификат (.csr)
  • PKCS #12 (RFC 7292) формат экспорта секретного ключа который вместе с сертификатом и путём сертификации ( .pfx или .p12).

Форматы хранения сертификатов

Основной формат хранения сертификатов X.509 - DER, однако для удобства пересылки по электронной почте его часто дополнительно кодируют в формат PEM (Privacy Enhanced Mail RFC 1421). PEM сам по себе довольно большой стандарт, но из взято только кодирование по алгоритму Base64 и обрамление полученного текста границами:

-----BEGIN label -----
-----END label -----

Для секретных ключей RSA (PKCS#1) используется традиционная форма label, похоже, не описанная в стандартах - RSA PRIVATE KEY.

RFC 7468 описывает форматы label для разных типов ключей и сертификатов

  • CERTIFICATE - сертификат X.509
  • PUBLIC KEY - публичный ключ X.509
  • X509 CRL - список отозванных сертификатов
  • PKCS7 - PKCS#7
  • PRIVATE KEY - PKCS#8
  • ENCRYPTED PRIVATE KEY - RFC 5958
  • CERTIFICATE REQUEST - PKCS#10

За пределами границ BEGIN и END в файл с сертификатом может быть добавлена человекочитаемая версия данных.

Конвертация форматов

Вывод в человекочитаемом формате. noout - отключение вывода в формате PEM:

openssl x509 -in certificate.cer -noout -text

Конвертация PEM -> DER и наоборот:

openssl x509 -inform pem -in certificate.pem -outform der -out certificate.cer
openssl x509 -inform der -in certificate.cer -outform pem -out certificate.pem

Создание файла PFX:

openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile CA.crt

Извлечение приватного ключа RSA из PKCS#8:

openssl pkcs8 -nocrypt -in pkcs8.pem -out pkcs1.pem

CA Bundle

CA Bundle - связка CA - это не особый формат, а просто набор открытых ключей (сертификатов) доверенных центров сертификации в формате PEM, склеенных в один текстовый файл. Формат придуман фирмой Netscape. В Linux CentOS 7 файл /etc/pki/tls/certs/ca-bundle.crt ставится с пакетом ca-certificates-2018.2.22-70. Создать CA Bundle из отдельных файлов можно стандартными средствами ОС:

cat *.pem > ca_bundle.crt

Ссылки

Статья про кроссплатформенное средство просмотра сертификатов

Шифрование/дешифрование

Краткая сводка полезных команд (исключая работу с сертификатами)

Генерация случайных данных/паролей

#сгенерировать 12 байт/16 символов в base64
openssl rand -base64 12

Хэш пароля. Первый вариант - классический DES из passwd, второй - MD5 из shadow. Если salt опустить, то будет сгенерирована случайная строка.

openssl passwd -salt 8E MySecret
openssl passwd -1 -salt sXiKzkus MySecret

Криптографический дайджест файла. В Linux можно использовать эквивалентные команды md5sum, sha1sum.

openssl dgst -md5 filename
openssl dgst -sha1 filename

(Де)Кодирование в BASE64

openssl enc -base64 < file.txt
openssl enc -base64 -in file.txt
openssl enc -base64 -in file.txt -out file.txt.enc

#Декодирование
openssl enc -base64 -d < file.txt.enc

Шифрование симметричными шифрами. Пароль можно вводить интерактивно, читать из файла или указывать в командной строке

#список алгоритмов
openssl list-cipher-commands

#шифрование
openssl enc -des -in file.txt -out file.enc
openssl enc -des -in file.txt -out file.enc -pass pass:mySillyPassword
openssl enc -des -in file.txt -out file.enc -pass file:/path/to/secret/password.txt

#шифрование + кодирование в base64
openssl enc -des -a -in file.txt -out file.asc

#дешифрование
openssl enc -d -des -a -in file.asc -out file.txt

Клиент/сервер

SSL/TLS клиент. На STDERR выводится информация о сертификате. После подключения можно вручную вводить команды соответствующего протокола. TLS доступен только для определённых протоколов.

openssl s_client -connect remote.host:443
openssl s_client -connect remote.host:25 -starttls smtp

Сохранение сертификата в файл penssl s_client -connect remote.host:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p'

Веб сервер с корнем в текущем каталоге. По умолчанию слушает порт 4433.

 openssl s_server -accept 443 -cert mycert.pem -WWW