// Engineering Log

HTTPS и веб-сервер на практике: Часть 2 — Форматы сертификатов PEM, DER, PFX и CSR: чем отличаются и как конвертировать

Опубликовано 30.10.2026 · Автор:

// Быстрый маршрут

Эта статья относится к теме Безопасность и защита.

Удостоверяющий центр прислал архив с файлами .crt, .ca-bundle и .p7b, а сервер просит .pfx. Или наоборот: из Windows выгрузили .pfx, а Nginx нужны отдельно сертификат и ключ. Внутри всех этих файлов одни и те же сущности — сертификат, закрытый ключ, промежуточные сертификаты, — различается только упаковка. Ниже — как узнать, что лежит в файле, как перевести его в нужный формат и как не ошибиться при сборке цепочки. Как устроены сертификат и цепочка доверия — в статье «Что такое HTTPS и как работает рукопожатие TLS».

Что бывает внутри

  • Сертификат — открытый ключ с данными о владельце, подписанный центром. Не секрет, его отдаёт сервер каждому клиенту.
  • Закрытый ключ — секрет. Кто им владеет, тот может выдавать себя за ваш сайт.
  • Промежуточные сертификаты (chain, bundle, CA bundle) — звенья между вашим сертификатом и корнем центра.
  • Запрос на подпись (CSR) — открытый ключ и имена, которые вы отправляете центру, чтобы получить сертификат.

Форматы

PEM — текст в Base64 между строками-маркерами. Самый распространённый формат в Linux: его используют Nginx, Apache, HAProxy, почтовые серверы. В одном файле может лежать несколько блоков подряд.

-----BEGIN CERTIFICATE-----
MIIFBTCCA+2gAwIBAgISA...
-----END CERTIFICATE-----

Расширения — .pem, .crt, .cer, .key, .ca-bundle. Расширение ничего не гарантирует: .crt может оказаться и PEM, и DER. Тип содержимого определяет строка-маркер:

МаркерЧто внутри
BEGIN CERTIFICATEсертификат
BEGIN CERTIFICATE REQUESTCSR
BEGIN PRIVATE KEYзакрытый ключ в формате PKCS#8 (любой алгоритм)
BEGIN ENCRYPTED PRIVATE KEYключ PKCS#8, зашифрованный паролем
BEGIN RSA PRIVATE KEYключ RSA в старом формате PKCS#1
BEGIN EC PRIVATE KEYключ ECDSA в старом формате
BEGIN PKCS7контейнер PKCS#7 с цепочкой

DER — тот же сертификат в двоичном виде, без Base64. Расширения .der, .cer. Встречается в Windows и Java. В текстовом редакторе выглядит как мусор.

PKCS#7 (.p7b, .p7c) — контейнер с одним или несколькими сертификатами, обычно цепочкой. Закрытого ключа в нём нет. Так цепочку отдают многие коммерческие центры и Windows.

PKCS#12 (.pfx, .p12) — контейнер со всем сразу: сертификат, закрытый ключ и цепочка, защищённые паролем. Используется в Windows (IIS, Exchange, RDP), в Java, для импорта клиентских сертификатов в браузер и на телефон.

JKS — хранилище ключей Java. С Java 9 по умолчанию используется PKCS#12, и JKS встречается только в старых системах.

Как узнать, что в файле

bash
head -1 file.crt                                   # PEM — видна строка BEGIN
openssl x509 -in file.crt -noout -subject -issuer -dates         # сертификат PEM
openssl x509 -in file.cer -inform der -noout -subject -dates     # сертификат DER
openssl req -in file.csr -noout -text -verify                    # CSR
openssl pkey -in file.key -noout -text | head -1                 # ключ: алгоритм и размер
openssl pkcs12 -in file.pfx -info -noout                         # PFX (спросит пароль)
openssl pkcs7 -in file.p7b -print_certs -noout                   # P7B

Сколько сертификатов в PEM-файле и какие:

bash
openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout

Конвертация

DER → PEM и обратно:

bash
openssl x509 -in cert.der -inform der -out cert.pem
openssl x509 -in cert.pem -outform der -out cert.der

P7B → PEM (получить цепочку в виде обычных сертификатов):

bash
openssl pkcs7 -in chain.p7b -print_certs -out chain.pem

В выводе перед каждым сертификатом будут строки subject= и issuer= — Nginx их игнорирует, но для аккуратности их можно удалить.

PFX → PEM (из Windows в Linux):

bash
openssl pkcs12 -in site.pfx -clcerts -nokeys -out cert.pem          # сертификат сайта
openssl pkcs12 -in site.pfx -cacerts -nokeys -out chain.pem         # промежуточные
openssl pkcs12 -in site.pfx -nocerts -nodes -out privkey.pem        # ключ без пароля

-nodes сохраняет ключ незашифрованным — иначе Nginx при каждом запуске будет спрашивать пароль. Сразу ограничьте права: chmod 600 privkey.pem.

Если OpenSSL 3 отвечает unsupported algorithm (RC2-40-CBC) или Algorithm (RC2-40-CBC : 0), Properties (), файл зашифрован устаревшими алгоритмами, которые по умолчанию отключены. Добавьте -legacy:

bash
openssl pkcs12 -legacy -in site.pfx -nocerts -nodes -out privkey.pem

PEM → PFX (из Linux в Windows или Java):

bash
openssl pkcs12 -export -out site.pfx \
  -inkey privkey.pem -in cert.pem -certfile chain.pem \
  -name "example.ru"

OpenSSL 3 шифрует PFX алгоритмом AES-256. Старые системы (Windows Server 2016 и раньше, некоторые версии Java) такой файл не открывают и сообщают о неверном пароле. Для них соберите PFX со старыми алгоритмами:

bash
openssl pkcs12 -export -legacy -out site-legacy.pfx -inkey privkey.pem -in cert.pem -certfile chain.pem

PFX → JKS (для Java-приложений, которым нужен именно JKS):

bash
keytool -importkeystore -srckeystore site.pfx -srcstoretype pkcs12 \
  -destkeystore site.jks -deststoretype jks

Ключ: снять пароль, перевести в PKCS#8:

bash
openssl pkey -in encrypted.key -out privkey.pem           # спросит пароль, сохранит без него
openssl pkcs8 -topk8 -nocrypt -in rsa-pkcs1.key -out privkey.pem

Сборка цепочки (fullchain)

Nginx и HAProxy ждут один файл: сначала сертификат сайта, затем промежуточные по порядку, корневой — не нужен.

bash
cat example.ru.crt intermediate.crt > fullchain.pem

Ошибки при сборке:

  • не тот порядок — Nginx при запуске берёт ключ к первому сертификату в файле и выдаёт key values mismatch, если первым стоит промежуточный;
  • нет перевода строки в конце файла — при склейке получается -----END CERTIFICATE----------BEGIN CERTIFICATE----- в одной строке, и второй сертификат не читается. Проверка: grep -c 'BEGIN CERTIFICATE' fullchain.pem должен совпадать с числом сертификатов;
  • добавлен корневой — не ошибка, но лишние байты в каждом рукопожатии; а старый корень с истёкшим сроком может сбить с толку некоторые клиенты;
  • перепутан промежуточный — центр выпускает сертификаты от нескольких промежуточных; берите тот, который указан в поле issuer вашего сертификата.

Для HAProxy сертификат, цепочка и ключ складываются в один файл: cat fullchain.pem privkey.pem > /etc/haproxy/certs/example.ru.pem.

Как создать CSR

Для коммерческого центра или внутреннего CA нужен ключ и запрос. Ключ создаётся у вас и никуда не отправляется.

bash
# ключ ECDSA P-256
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out example.ru.key

# CSR с именами в SAN (OpenSSL 1.1.1+)
openssl req -new -key example.ru.key -out example.ru.csr \
  -subj "/CN=example.ru" \
  -addext "subjectAltName=DNS:example.ru,DNS:www.example.ru"

Для ключа RSA: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out example.ru.key.

Имена указывайте в SAN: браузеры проверяют только его, поле CN для проверки имени не используется. Центры сами добавляют SAN из CN, но лучше не рассчитывать на это.

RSA или ECDSA

  • ECDSA P-256 — ключ 256 бит по стойкости сопоставим с RSA 3072, сертификат меньше, подпись при рукопожатии быстрее. Поддерживается всеми браузерами и ОС последних десяти лет.
  • RSA 2048 — нужен только для очень старых клиентов: встроенных устройств, старых Java и Windows XP.

Nginx умеет отдавать оба сертификата одновременно и выбирает подходящий по возможностям клиента:

nginx
ssl_certificate     /etc/ssl/example.ru.ecdsa.crt;
ssl_certificate_key /etc/ssl/example.ru.ecdsa.key;
ssl_certificate     /etc/ssl/example.ru.rsa.crt;
ssl_certificate_key /etc/ssl/example.ru.rsa.key;

certbot выпускает ECDSA по умолчанию с версии 2.0; для RSA — --key-type rsa.

Ошибки Nginx при загрузке сертификата

  • PEM_read_bio_X509_AUX() failed (SSL: error:0480006C:PEM routines::no start line) — файл не в PEM: вы указали DER, PFX или P7B. Конвертируйте.

  • SSL_CTX_use_PrivateKey(...) failed (SSL: error:05800074:x509 certificate routines::key values mismatch) — ключ не от этого сертификата или первым в fullchain стоит не сертификат сайта. Сравнить ключ и сертификат:

    bash
    openssl x509 -in cert.pem -noout -pubkey | openssl sha256
    openssl pkey -in privkey.pem -pubout | openssl sha256
  • Nginx при запуске спрашивает пароль или не стартует через systemd — ключ зашифрован; снимите пароль (openssl pkey) и защитите файл правами.

  • cannot load certificate ... Permission denied — Nginx читает сертификаты от root при запуске, но проверьте права и SELinux-контекст, если файлы лежат не в /etc.

После любых изменений: nginx -t && systemctl reload nginx, затем проверка через openssl s_client — подробно в статье «Отладка TLS».

Хранение ключей

  • Права 600 на ключ, владелец — root; каталог — 700.
  • Ключ не пересылают по почте и в мессенджерах вместе с сертификатом. Если нужно перенести PFX — пароль передают отдельным каналом.
  • Ключ не кладут в репозиторий. Если это произошло, ключ считается скомпрометированным: сертификат нужно отозвать и выпустить новый с новым ключом.
  • При выпуске нового сертификата лучше генерировать и новый ключ.

// Похожая задача

Если у вас похожая ситуация

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

Тема статьи

Безопасность и защита

SSL, hardening, доступы, защита сервисов и безопасные конфигурации.

Часто с этим приходят

  • Настроить SSL, сертификаты и безопасные подключения
  • Ограничить доступы и закрыть лишние точки входа
  • Усилить конфигурацию сервера и сервисов

// Следующий шаг

Если вам нужна не только статья, а помощь по этой теме, удобнее сразу перейти в услугу. Главная и подборка материалов остаются рядом.

Открыть услуги

// Reviews

Отзывы по теме

Спасибо Михаилу за отзывчивость. Созвонились, объяснил как сделать самому. Обращаюсь уже второй раз, все супер и оперативно.

Спасибо Михаилу за отзывчивость. Созвонились, объяснил как сделать самому. Обращаюсь уже второй раз, все супер и оперативно.

kireevk

kireevk

Консультация по nginx proxy manager и portainer

25.02.2025 · ★ 5/5

Освоившийся покупатель
apande

apande

Настройка nginx и opencart

07.09.2024 · ★ 5/5

Очень мощный покупатель
kireevk

kireevk

Диагностика Nginx Proxy Manager в docker контейнере и решение проблемы

15.03.2024 · ★ 5/5

Освоившийся покупатель

// Contact

Нужна помощь?

Свяжись со мной и я помогу решить проблему

Написать в Telegram

Отвечаю в течение рабочего дня (03:00–13:00 GMT)

Или оставьте заявку здесь:

Подтвердите, что вы не бот.

Написать и получить быстрый ответ