Существует большое разнообразие форматов, в которых создаются сертификаты и приватные ключи для них. Часто они упаковываются в защищенные хранилища. Формат кодирования сертификатов, ключей и хранилищ должен соответствовать тому, что ожидает ваше приложение, в противном случае их не получится прочитать.
В этой статье мы рассмотрим используемые форматы и конвертирование из одного формата в другой.
Форматы сертификатов
Начнем с того, что расширение файла сертификата не влияет на тип его содержимого, но может служить подсказкой, что ожидать внутри. Сертификаты часто имеют расширения .crt
, .pem
, .cer
, однако, чаще всего они не имеют никаких отличий.
Итак, сертификаты могут быть представлены в текстовом формате Base64 ASCII и в бинарном виде — DER. Чаще всего используется текстовый формат. Сам по себе сертификат и ключи для него должны удовлетворять определенному стандарту — самый популярный X.509.
Общие применения сертификатов X.509 включают в себя:
- SSL /TLS HTTPS для аутентифицированного и зашифрованного просмотра веб-страниц
- Подписанный и зашифрованный адрес электронной почты через S/MIME протокол
- Подписание кода
- Подписание документов
- Аутентификация клиента
- Государственный электронный идентификатор
Самый часто встречающийся таким образом вид — X.509 PEM формат. Такой файл начинается строкой
-----BEGIN CERTIFICATE-----
и заканчивается
-----END CERTIFICATE-----
Один файл может содержать цепочку сертификатов, каждый из которых будет иметь указанный заголовок и колонтитул в конце.
Посмотреть содержимое сертификата можно командой:
openssl x509 -in CERTIFICATE.pem -text -noout
Также, сертификат может быть зашифрованным и начинаться со строки
-----BEGIN TRUSTED CERTIFICATE-----
Получить обычный PEM из него можно командой:
openssl x509 -in CERTIFICATE.crt -outform PEM
Чтобы конвертировать ключ в DER формат:
openssl x509 -outform der -in CERTIFICATE.pem -out CERTIFICATE.der
Ключи и алгоритмы
Сертификат должен подписываться определённой парой ключей — приватного и публичного. Существует два основных алгоритма шифрования шифрования для ключей — RSA и ECC.
- RSA (алгоритм международного стандарта): один из самых ранних широко используемых алгоритмов. Он применим к более широкому диапазону и обеспечивает более высокую совместимость по сравнению с ECC. Однако обычно его длина составляет 2048 бит, что требует больше ресурсов сервера.
- ECC (криптография с эллиптической кривой): новый основной алгоритм. Обычно его длина составляет 256 бит (256-битный ключ ECC эквивалентен 3072-битному ключу RSA), что делает его более безопасным и обеспечивает более сильные возможности защиты от атак. Более того, вычисление ECC происходит быстрее, чем RSA, и, следовательно, обеспечивает более высокую эффективность и потребляет меньше ресурсов сервера. ECC ключи имеют меньший размер.
В корпоративном сегменте и, в частности, в серверах Windows PKI чаще используется современный EC алгоритм, в то время как в интернете и в старых серверах Linux для совместимости обычно используется RSA. Не все центры сертификации (CA) уже имеют выписывать сертификаты для EC ключей. В частности, проблема заключается в использовании гибридного SSL, когда ECC ключи используются с RSA рутовыми сертификатами.
Также существуют и другие алгоритмы с открытым ключом, такие как DSA. Но он фактически реже в веб-серверах. Его основное применение — новая версия SSH2, которая считается более защищенной.
В конечном итоге, поддержка того или иного алгоритма упирается в ту библиотеку или версию библиотеки cryptlib, которая используется в вашем приложении.
Стоит отметить, что ECDSA, первоначальная версия ECC, является вариантом DSA. ECDSA предлагает эквивалентные уровни криптографической стойкости на количество битов, что и ECC.
Процессинг ключей
Создать ключ в PEM формате с алгоритмом EC можно так:
openssl ecparam -genkey -name secp384r1 -out privkey.pem
- Опция -genkey указывает OpenSSL сгенерировать ключ EC.
- Параметр -name сообщает OpenSSL, какую кривую использовать. secp384r1 — это кривая P-384.
- Параметр -out сообщает OpenSSL о необходимости записи вывода в файл.
Проверить EC ключ можно так:
openssl ec -in privkey.pem -noout -text
Такой ключ в текстовом файле будет начинаться с
-----BEGIN PRIVATE KEY-----
Но можно записать ключ и в зашифрованном виде. В таком случае файл будет начинаться с
-----BEGIN ENCRYPTED PRIVATE KEY-----
Рассмотрим на примере ключей RSA, как наиболее популярных. Дело в том, что традиционный ключ RSA удовлетворяет стандарту PKCS#1 (Public Key Cryptography Standards) и представлены к незашифрованном виде. Такой ключ выглядит следующим образом:
-----BEGIN RSA PRIVATE KEY-----
Его можно конфертировать в более современный стандарт PKCS#8, и тогда он будет выглядеть так:
-----BEGIN PRIVATE KEY-----
Его можно дополнительно зашифровать, используются алгоритмы PBE with SHA-1 и AES/RC и шифрование на основе пароля. При создании такого ключа нужно будет ввести PEM passphrase. В зашифрованном виде он будет выглядеть вот так:
-----BEGIN ENCRYPTED PRIVATE KEY-----
PKCS#8 поддерживает не только RSA ключи, в то время как PKCS#1 описывает только их. Эти стандарты фактически описывают работу с ключами и создание файлов для них.
Общепринятым вариантом считается использование X.509 с PKCS#8.
Чтобы преобразовать PKCS#1 в PKCS#8, используется команда:
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs1.key -out pkcs8.key
Создаем пару RSA ключей длиной 3072 бит, зашифрованный AES-128. Пароль вводим с консоли:
openssl genrsa -aes128 -passout stdin -out privkey.pem 3072
Экспортируем публичный ключ:
openssl rsa -in privkey.pem -passin stdin -pubout -out privkey.pub
Также ключи другого алгоритма можно создать, используя параметр genpkey:
openssl genpkey -aes-256-cbc -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:4096
А для EC ключа так:
openssl ecparam -name prime256v1 -genkey -noout -out key.pem
Контейнеры
PKCS#7 (также известный как P7B) — это контейнерный формат для цифровых сертификатов, который чаще всего встречается в контексте серверов Windows и Java и обычно имеет расширение .p7b
. Файлы PKCS#7 не используются для хранения закрытых ключей.
PKCS#12 (также известный как PKCS12 или PFX) является распространенным двоичным форматом для хранения цепочки сертификатов и закрытого ключа в одном зашифрованном файле и обычно имеет расширения имени файла. .p12
или .pfx
.
JKS формат — формат Java контейнеров. Для манипуляция с ним используется утилита keytool, которая входит в поставку Java RE.
Контейнеры могут содержать несколько объектов, к которым можно обращаться по именам: trusted certificate, trusted keypair.
Создание p7b контейнера с несколькими сертификатами:
openssl crl2pkcs7 -nocrl -certfile CERTIFICATE.pem -certfile MORE.pem -out CERTIFICATE.p7b
Создание p12 контейнера с сертификатом и приватным ключом. Публичный ключ содержится в сертификате. Также добавляется дополнительный сертификат:
openssl pkcs12 -export -out CERTIFICATE.pfx -inkey PRIVATEKEY.key -in CERTIFICATE.crt -certfile MORE.crt
Контейнер p12 защищается паролем при создании.
Чтобы прочитать содержимое контейнера, используется ключ -info
openssl pkcs12 -info -in CERTIFICATE.pfx -nodes
Доступные опции команды:
- -nodes
Ключ означает не использовать шифрование для ключей, вывести в незашифрованном виде (при этом спросят пароль для расшифрования). - -noout
Эта опция запрещает вывод ключей и сертификатов в выходную версию файла PKCS#12. - -clcerts
Выводить только сертификаты клиента (не сертификаты CA). - -cacerts
Выводить только сертификаты CA (не сертификаты клиента). - -nocerts
Сертификаты вообще не выводятся. - -nokeys
Приватные ключи выводиться не будут.
Keytool и java контейнеры
Ключевой особенностью обращения к объектам внутри такого контейнера является использование алиасов.
- Создаем хранилище, генерируя при этом ключ:
keytool -genkey -alias host1 -keyalg RSA -keystore KeyStore.jks -keysize 2048
- Создаем CSR запрос, используя ключ из хранилища:
keytool -certreq -alias host1 -keystore KeyStore.jks -file mydomain.csr
- Добавляем в хранилище промежуточные и рутовые CA сертификаты:
keytool -import -trustcacerts -alias root -file root.crt -keystore KeyStore.jks keytool -import -trustcacerts -alias intermediate -file intermediate.crt -keystore KeyStore.jks
- Добавляем сертификат, созданный на базе ключа из пункта 1.
keytool -import -trustcacerts -alias host1 -file host1.crt -keystore KeyStore.jks
Посмотреть содержимое хранилища можно командой:
keytool -list -v -keystore keystore.p12 -storetype PKCS12 -storepass <>
А экспортировать сертификат из него так:
keytool -exportcert -keystore keystore.p12 -storetype PKCS12 -storepass <> -file host1.crt -alias host1 -rfc
Для работы (создание, просмотр, экспорт) в графическом интерфейсе с любым типом контейнеров рекомендую утилиту KeyStore Explorer — она доступна для всех операционных систем.