Eu tenho um certificado de entidade/servidor final que possui um certificado intermediário e raiz. Quando estou cat
no certificado da entidade final, vejo apenas uma tag BEGIN
e END
. É o único certificado da entidade final.
Existe alguma maneira de visualizar o conteúdo do certificado intermediário e raiz. Eu preciso apenas do conteúdo BEGIN
e END
da tag.
No Windows, posso ver a cadeia completa de certificados no "Caminho de certificação". Abaixo está o exemplo do certificado do Stack Exchange.
A partir daí posso realizar umVer certificadoe exportá-los. Posso fazer isso tanto para root quanto para intermediário no Windows. Estou procurando esse mesmo método no Linux.
Responder1
Em um site, você pode fazer:
openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null
Isso mostrará a cadeia de certificados e todos os certificados que o servidor apresentou.
Agora, se eu salvar esses dois certificados em arquivos, posso usar 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
A -untrusted
opção é utilizada para fornecer o(s) certificado(s) intermediário(s); se.crt
é o certificado a ser verificado. O resultado profundidade = 2 veio do armazenamento de CA confiável do sistema.
Se você não tiver os certificados intermediários, não poderá realizar a verificação. É assim que o X.509 funciona.
Dependendo do certificado, ele pode conter um URI para obter o intermediário. Como exemplo, openssl x509 -in se.crt -noout -text
contém:
Authority Information Access:
OCSP - URI:http://ocsp.digicert.com
CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt
Esse URI "CA Issuers" aponta para o certificado intermediário (no formato DER, portanto, você precisa usá-lo openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pem
para convertê-lo para uso posterior pelo OpenSSL).
Se você executar , openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash
obterá 244b5494
, que poderá procurar no armazenamento CA raiz do sistema em /etc/ssl/certs/244b5494.0
(basta anexar .0
ao nome).
Não acho que exista um comando OpenSSL fácil e agradável para fazer tudo isso por você.
Responder2
dr - magia bash de um liner para despejar todos os certificados da cadeia
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
Explicação em 2 passos
Para despejar todos os certificados da cadeia no diretório atual como 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}'
A faixa bônus para renomeá-los com seu nome comum:
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
Responder3
Descobri que com a opção -verify 5
openssl vai fundo na cadeia mostrando todo o certificado, mesmo aquele não incluído na implantação do seu certificado.
Se você realmente deseja entender qual cadeia é fornecida com seu certificado, execute:
openssl s_client -showcerts -partial_chain -connect YOUR_ENDPOINT:443 < /dev/null |less
Responder4
O procedimento acima não funcionou para mim quando eu estava usando um certificado Lets Encrypt Free Wildcard.
Para ser mais específico:
eu tenho um cluster Kubernetes + controlador de entrada configurado usando um certificado curinga gratuito Lets Encrypt para *.mydomain.dev, que hospeda os dois nomes de domínio a seguir:
- grafana.meudominio.dev
- prometheus.meudominio.dev
Eu tive que adicionar o sinalizador -servername seguindo este site: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}'
Eu também ajustei a cadeia para que ela me fornecesse o certificado completo + intermediário + raiz para a saída padrão e ocultasse o ruído stderr.
Na verdade... Ao testar descobri que isso não me dá a 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
Fornece um valor diferente (e ao testar algumas coisas, esse é o valor que funciona).