Как извлечь корневой центр сертификации и подчиненный центр сертификации из цепочки сертификатов в Linux?

Как извлечь корневой центр сертификации и подчиненный центр сертификации из цепочки сертификатов в Linux?

У меня есть сертификат конечного объекта/сервера, который имеет промежуточный и корневой сертификат. Когда я 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 5openssl проникает глубоко в цепочку, показывая все сертификаты, даже те, которые не включены в ваше развертывание сертификатов.

Если вы действительно хотите понять, какая цепочка предоставлена ​​вашим сертификатом, вам следует выполнить:

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 Дает другое значение (и при тестировании некоторых вещей это значение является тем, которое работает).

Связанный контент