У меня есть сертификат конечного объекта/сервера, который имеет промежуточный и корневой сертификат. Когда я cat
нахожу сертификат конечного объекта, я вижу только один BEGIN
и END
тег. Это единственный сертификат конечного объекта.
Есть ли способ просмотреть содержимое промежуточного и корневого сертификата. Мне нужно только содержимое BEGIN
и END
тег.
В Windows я вижу полную цепочку сертификатов из "Certification Path". Ниже приведен пример сертификата Stack Exchange.
Оттуда я могу выполнитьПосмотреть сертификати экспортировать их. Я могу сделать это как для root, так и для intermediate в Windows. Я ищу этот же метод в Linux.
решение1
На веб-сайте вы можете сделать следующее:
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
Это покажет цепочку сертификатов и все сертификаты, представленные сервером.
Теперь, если я сохраню эти два сертификата в файлы, я могу использовать openssl verify
:
$ openssl verify -show_chain -untrusted dc-sha2.crt se.crt
se.crt: OK
Chain:
depth=0: C = US, ST = NY, L = New York, O = "Stack Exchange, Inc.", CN = *.stackexchange.com (untrusted)
depth=1: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA (untrusted)
depth=2: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
Опция -untrusted
используется для предоставления промежуточного сертификата(ов); se.crt
это сертификат для проверки. Результат глубины=2 пришел из системного хранилища доверенных CA.
Если у вас нет промежуточного сертификата(ов), вы не сможете выполнить проверку. Так работает X.509.
В зависимости от сертификата он может содержать URI для получения промежуточного элемента. Например, openssl x509 -in se.crt -noout -text
содержит:
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
Этот URI «CA Issuers» указывает на промежуточный сертификат (в формате DER, поэтому вам необходимо openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem
преобразовать его для дальнейшего использования OpenSSL).
Если вы запустите , openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash
то получите 244b5494
, который можно найти в хранилище корневых ЦС системы по адресу /etc/ssl/certs/244b5494.0
(просто добавьте .0
к имени).
Я не думаю, что существует удобная и простая команда OpenSSL, которая сделает все это за вас.
решение2
tl;dr - однострочная bash-магия для сброса всех сертификатов в цепочке
openssl s_client -showcerts -verify 5 -connect wikipedia.org:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
echo "${newname}"; mv "${cert}" "${newname}"
done
Объяснение в 2 шага
Чтобы выгрузить все сертификаты в цепочке в текущий каталог, выполните следующие действия cert${chain_number}.pem
:
openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null |
awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{ if(/BEGIN CERTIFICATE/){a++}; out="cert"a".pem"; print >out}'
Бонус-трек, чтобы переименовать их в их общепринятое название:
for cert in *.pem; do
newname=$(openssl x509 -noout -subject -in $cert | sed -nE 's/.*CN ?= ?(.*)/\1/; s/[ ,.*]/_/g; s/__/_/g; s/_-_/-/; s/^_//g;p' | tr '[:upper:]' '[:lower:]').pem
mv $cert $newname
done
решение3
Я обнаружил, что при использовании этой опции -verify 5
openssl проникает глубоко в цепочку, показывая все сертификаты, даже те, которые не включены в ваше развертывание сертификатов.
Если вы действительно хотите понять, какая цепочка предоставлена вашим сертификатом, вам следует выполнить:
openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
решение4
Указанное выше не сработало у меня, когда я использовал Lets Encrypt Free Wildcard Certificate.
Если быть точнее:
у меня есть Kubernetes Cluster + Ingress Controller, настроенный с использованием Lets Encrypt Free Wildcard Certificate для *.mydomain.dev, он размещает следующие 2 доменных имени:
- графана.мойдомен.dev
- prometheus.mydomain.dev
Мне пришлось добавить флаг -servername, следуя указаниям этого сайта:https://community.letsencrypt.org/t/where-can-i-download-the-trusted-root-ca-certificates-for-lets-encrypt/33241/2
export DOMAIN=grafana.mydomain.dev
openssl s_client -showcerts -verify 5 -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
Я также подправил цепочку так, чтобы она выдавала мне полный сертификат + промежуточный + корневой поток на стандартный вывод и скрывала шум stderr.
На самом деле... При тестировании я обнаружил, что это не дает мне CA...
openssl s_client -showcerts -verify 5 -connect letsencrypt.org:443 < /dev/null 2> /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; print}'
curl https://letsencrypt.org/certs/isrgrootx1.pem
Дает другое значение (и при тестировании некоторых вещей это значение является тем, которое работает).