como baixar o certificado ssl de um site?

Respostas:

246

Para fazer o download do certificado, você precisa usar o cliente incorporado ao openssl da seguinte maneira:

echo -n | openssl s_client -connect HOST:PORTNUMBER \
    | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > /tmp/$SERVERNAME.cert

Isso salvará o certificado em /tmp/$SERVERNAME.cert.

Você pode usar -showcertsse quiser fazer o download de todos os certificados na cadeia. Mas se você deseja apenas baixar o certificado do servidor, não há necessidade de especificar-showcerts

echo -n dá uma resposta ao servidor, para que a conexão seja liberada

sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'remove informações sobre a cadeia de certificados e detalhes da conexão. Este é o formato preferido para importar o certificado para outros keystores.

Sean Reifschneider
fonte
9
compreendo que você não apenas deu uma boa resposta, mas também uma explicação precisa.
marco.m
Será que -showcertsmostrar o certificado de servidor / folha também? Eu pensei que ele só exibia intermediários quando essa opção foi incluída.
Mike B
Como a resposta disse, s_clientsempre mostra o certificado do servidor (se houver um, ou seja, o servidor responde ao hello e não escolhe um conjunto anônimo). -showcertsmostra todos os certificados recebidos, o certificado do servidor primeiro e depois os intermediários e / ou raiz.
Dave_thompson_085 28/05
4
isso não funciona nas presenças de um proxy.
Frederick Nord
2
Isso também não funciona com servidores que usam SNI (vários certificados / domínios em um único endereço IP). Para evitar problemas, especifique o parâmetro servername do openssl: openssl s_client -connect HOST: PORTNUMBER -servername CN
verhage
60

Eu encontrei a resposta. Openssl fornece.

openssl s_client -connect $ {REMHOST}: $ {REMPORT}

RainDoctor
fonte
2
também openssl x509 -text <<EOF cert-text EOFpara ver detalhes do certificado
mpapis
2
sudo rm -f cert.pem && sudo echo -n | openssl s_client -connect localhost:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./cert.pemcortesia de serverfault.com/questions/139728/…
pulkitsinghal
isso faz o mesmo e ignora o sedhack.
Phs
Isso apenas verifica um certificado, e se o serviço fizer parte de um grupo de servidores com balanceamento de carga, dos quais cada um possui um certificado diferente, possivelmente assinado por uma CA raiz diferente? Ou, em outras palavras, um ataque mitm pode deixar essa solicitação entrar no site real e direcionar outras solicitações para seus servidores. Existem maneiras de verificar isso? E para obter uma lista de todos os certificados que um domínio realmente possui?
Jens Timmerman
@JensTimmerman "Ou, em outras palavras, um ataque mitm pode deixar essa solicitação entrar no site real e depois direcionar outras solicitações para seus servidores". Isso não é possível, a menos que o man-in-the-middle tenha um certificado válido para o servidor de destino (ou o cliente seja bobo e não verifique o certificado do servidor). Evidentemente, se o servidor às vezes oferecer um certificado diferente, você pode esperar obter provavelmente todos eles repetindo tentativas de conexão.
David Tonhofer 04/08/2015
22

A ferramenta cliente GNUTLS,,gnutls-cli também pode facilitar isso:

gnutls-cli --print-cert www.example.com \
        < /dev/null \
        > www.example.com.certs

O programa foi projetado para fornecer um cliente interativo ao site, portanto, você precisa fornecer uma entrada vazia (neste exemplo, de /dev/null) para finalizar a sessão interativa.

nariz grande
fonte
1
como ele faria com que os gnutls se conectassem através do proxy https (configurado em todo o sistema) e imprimissem o certificado que trocam?
Frederick Nord
9

com base na resposta @bignose, aqui está uma versão independente que se encaixa bem em, por exemplo, uma receita de chef:

sudo apt-get install gnutls-bin 
gnutls-cli --print-cert myserver.com </dev/null| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > myserver.crt
sudo cp myserver.crt /usr/local/share/ca-certificates/myserver.crt
sudo update-ca-certificates
oDDsKooL
fonte
6
true | openssl s_client -connect google.com:443 2>/dev/null | openssl x509

esse modo de openssl espera stdin, portanto, fornecemos via true |, isso se conecta ao servidor especificado no parâmetro -connect. 2>/dev/nullsilêncios (opcional), podemos passar toda a saída para o analisador x509, especificando o /dev/stdinuso do pipe de shell como o arquivo de entrada. E que o produto será apenas o -----BEGIN CERTIFICATE-----que -----END CERTIFICATE-----parte da s_clientsaída. Você pode redirecionar isso para um arquivo adicionando > google.com.pemao final do comando.


O melhor que posso dizer é que isso não verifica a cadeia de certificados, mas apenas a identidade SSL que o servidor final fornece.

ThorSummoner
fonte
2
(1) isso realmente não melhora as respostas de 6 anos atrás (2) x509lê stdin por padrão, portanto -in /dev/stdiné redundante (3) s_clientverifica se o certificado do servidor está corretamente conectado a uma âncora de confiança local (raiz) e não está vencido, mas você suprimiu as informações que mostrariam isso (4) NÃO verifica a revogação (5) verifica o nome no certificado do servidor apenas na versão 1.0.2 e depois não é o padrão (mas você pode verificar isso facilmente olhando o certificado )
dave_thompson_085
@ dave_thompson_085, a questão é como baixar o certificado, mas não mostrar as informações da cadeia. Eu gosto do openssl x509 muito melhor do que o sed em outra resposta.
Der_Meister 22/02
0

Sintaxe alternativa usando Ex e substituição de processo:

ex +'/BEGIN CERTIFICATE/,/END CERTIFICATE/p' <(echo | openssl s_client -showcerts -connect example.com:443) -scq > file.crt
kenorb
fonte