jak pobrać certyfikat ssl ze strony internetowej?

Odpowiedzi:

246

Aby pobrać certyfikat, musisz użyć klienta wbudowanego w openssl w następujący sposób:

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

To zapisze certyfikat /tmp/$SERVERNAME.cert.

Możesz użyć, -showcertsjeśli chcesz pobrać wszystkie certyfikaty w łańcuchu. Ale jeśli chcesz tylko pobrać certyfikat serwera, nie musisz tego określać-showcerts

echo -n daje odpowiedź do serwera, aby połączenie zostało zwolnione

sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'usuwa informacje o łańcuchu certyfikatów i szczegółach połączenia. Jest to preferowany format importowania certyfikatu do innych magazynów kluczy.

Sean Reifschneider
źródło
9
doceniamy, że nie tylko udzieliłeś dobrej odpowiedzi, ale także dokładne wyjaśnienie.
marco.m
Czy -showcertspokazuje również serwer / certyfikat certyfikatu? Myślałem, że wyświetla półprodukty tylko wtedy, gdy włączono ten przełącznik.
Mike B
Jak powiedziała odpowiedź, s_clientzawsze pokazuje certyfikat serwera (jeśli taki istnieje, tzn. Serwer odpowiada cześć i nie wybiera anonimowego pakietu). -showcertspokazuje wszystkie otrzymane certyfikaty, najpierw certyfikat serwera, a następnie półprodukty i / lub root.
dave_thompson_085
4
nie działa to jednak w obecności proxy.
Frederick Nord
2
To również nie działa z serwerami, które używają SNI (wiele certyfikatów / domen na jednym adresie IP). Aby uniknąć problemów, określ parametr parametru nazwa_serwera openssl: openssl s_client -connect HOST: PORTNUMBER -servername CN
verhage
60

Znalazłem odpowiedź Openssl zapewnia to.

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

RainDoctor
źródło
2
także, openssl x509 -text <<EOF cert-text EOFaby zobaczyć szczegóły certyfikatu
mpapis
2
sudo rm -f cert.pem && sudo echo -n | openssl s_client -connect localhost:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ./cert.pemdzięki uprzejmości serverfault.com/questions/139728/…
pulkitsinghal
to robi to samo i pomija sedsiekać.
phs
To tylko sprawdza jeden certyfikat, co jeśli usługa jest częścią grupy serwerów z równoważeniem obciążenia, z których każdy ma inny certyfikat, być może podpisany przez inny główny urząd certyfikacji? Innymi słowy, atak mitm może pozwolić temu żądaniu przejść do prawdziwej witryny, a następnie skierować inne żądania do jego serwerów. Czy są jakieś sposoby, aby to sprawdzić? A żeby uzyskać listę wszystkich certyfikatów, które naprawdę ma domena?
Jens Timmerman
@JensTimmerman „Innymi słowy, atak mitm może pozwolić, aby żądanie to przeszło do prawdziwej witryny, a następnie skierować inne żądania do jego serwerów”. Nie jest to możliwe, chyba że man-in-the-middle ma ważny certyfikat dla serwera docelowego (lub głupiutki klient nie sprawdza certyfikatu serwera). Oczywiście, jeśli serwer czasami oferuje inny certyfikat, możesz jedynie mieć nadzieję, że w końcu zdobędziesz je wszystkie, powtarzając próby połączenia.
David Tonhofer,
22

Gnutls narzędzie klienta, gnutls-climożna również zrobić to proste:

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

Program został zaprojektowany w celu zapewnienia interaktywnego klienta w witrynie, więc musisz podać mu puste dane wejściowe (w tym przykładzie od /dev/null), aby zakończyć sesję interaktywną.

duży nos
źródło
1
w jaki sposób miałby połączyć gnutls (skonfigurowany systemowo) z serwerem proxy HTTPS i wydrukować wymieniany certyfikat?
Frederick Nord
9

w oparciu o odpowiedź @bignose, oto samodzielna wersja, która dobrze pasuje np. do przepisu szefa kuchni:

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
źródło
6
true | openssl s_client -connect google.com:443 2>/dev/null | openssl x509

ten tryb openssl oczekuje stdin, więc zapewniamy go przez true |, to łączy się z serwerem określonym w parametrze -connect. 2>/dev/nullwycisza błędy (opcjonalnie), możemy przekazać całe wyjście do parsera x509, określając /dev/stdinużycie potoku powłoki jako pliku wejściowego. I że wyjście będzie tylko -----BEGIN CERTIFICATE-----do -----END CERTIFICATE-----części s_clientprodukcji. Możesz przekierować to do pliku, dodając > google.com.pemna końcu polecenia.


Jak najlepiej mogę powiedzieć, nie weryfikuje to łańcucha certyfikatów, może jedynie powiedzieć, jaką tożsamość ssl zapewnia serwer końcowy.

ThorSummoner
źródło
2
(1) to tak naprawdę nie poprawia odpowiedzi sprzed 6 lat (2) x509domyślnie czyta stdin, więc -in /dev/stdinjest redundantne (3) s_clientsprawdza, czy certyfikat serwera poprawnie łączy się z lokalną kotwicą zaufania (root) i jest nieaktualny, ale masz ukrył informacje, które by to pokazały (4), NIE sprawdza pod kątem odwołania (5) sprawdza nazwę w certyfikacie serwera tylko w wersji 1.0.2, a następnie domyślnie (ale można to łatwo sprawdzić, patrząc na certyfikat później)
dave_thompson_085,
@ dave_thompson_085, pytanie brzmi: jak pobrać certyfikat, ale nie wyświetlać informacji o łańcuchu. Lubię opensl x509 znacznie lepiej niż sed w innej odpowiedzi.
Der_Meister
0

Alternatywna składnia z użyciem Ex i podstawienia procesu:

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