Jak wyodrębnić główny urząd certyfikacji i podrzędny urząd certyfikacji z łańcucha certyfikatów w systemie Linux?

25

Mam certyfikat podmiotu końcowego / serwera, który ma certyfikat pośredni i główny. Kiedy jestem catna certyfikacie jednostki końcowej, widzę tylko jeden BEGINi ENDtag. Jest to jedyny certyfikat podmiotu końcowego.

Czy jest jakiś sposób, aby wyświetlić zawartość certyfikatu pośredniego i głównego? Potrzebuję tylko treści BEGINi ENDtagu.

W Windows widzę pełny łańcuch certyfikatów z „Ścieżki certyfikacji”. Poniżej znajduje się przykład certyfikatu Stack Exchange.

wprowadź opis zdjęcia tutaj

Stamtąd mogę wykonać Wyświetl certyfikat i wyeksportować je. Mogę to zrobić zarówno dla użytkownika root, jak i pośredniego w systemie Windows. Szukam tej samej metody w systemie Linux.

wprowadź opis zdjęcia tutaj

Anirban Nag „tintinmj”
źródło
Poinformuj nas, kto wydał ci ten certyfikat.
Rui F Ribeiro
@RuiFRibeiro Powiedzmy, że ktoś ... Chcę zobaczyć łańcuch certyfikatów wymiany stosu z tylko głównym certyfikatem w ręku.
Anirban Nag 'tintinmj'

Odpowiedzi:

25

Ze strony internetowej możesz:

openssl s_client -showcerts -verify 5 -connect stackexchange.com:443 < /dev/null

To pokaże łańcuch certyfikatów i wszystkie certyfikaty przedstawione przez serwer.

Teraz, jeśli zapiszę te dwa certyfikaty w plikach, mogę użyć 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

-untrustedOpcja jest używany w celu certyfikat pośredni (y); se.crtto certyfikat do weryfikacji. Wynik głębokość = 2 pochodzi z zaufanego systemu urzędu certyfikacji.

Jeśli nie masz certyfikatów pośrednich, nie możesz przeprowadzić weryfikacji. Tak właśnie działa X.509.

W zależności od certyfikatu może on zawierać identyfikator URI, z którego można uzyskać półprodukt. Jako przykład openssl x509 -in se.crt -noout -textzawiera:

        Authority Information Access: 
            OCSP - URI:http://ocsp.digicert.com
            CA Issuers - URI:http://cacerts.digicert.com/DigiCertSHA2HighAssuranceServerCA.crt

Ten identyfikator URI „wystawców urzędów certyfikacji” wskazuje na pośredni certyfikat (w formacie DER, więc musisz openssl x509 -inform der -in DigiCertSHA2HighAssuranceServerCA.crt -out DigiCertSHA2HighAssuranceServerCA.pemgo przekonwertować do dalszego wykorzystania przez OpenSSL).

Jeśli uruchomisz openssl x509 -in /tmp/DigiCertSHA2HighAssuranceServerCA.pem -noout -issuer_hash, otrzymasz 244b5494, którego możesz szukać w głównym systemie CA w sklepie /etc/ssl/certs/244b5494.0(wystarczy dołączyć .0do nazwy).

Nie sądzę, że istnieje łatwa, łatwa komenda OpenSSL, która zrobi to wszystko za Ciebie.

derobert
źródło
To jest główny problem. Nie mam przy sobie adresu URL. Mam tylko plik certyfikatu. Potrzebuję zaszyfrowanej treści między tagiem BEGINi END(które otrzymasz po catsamym pobraniu pliku .crt.
Anirban Nag 'tintinmj'
@ AnirbanNag'tintinmj 'Jeśli tylko chcesz zdekodować certyfikat, spróbujopenssl x509 -in file.crt -noout -text
derobert
Chcę zawartość pośredniej w root cert, która znajduje się między tagiem BEGINa END.
Anirban Nag 'tintinmj'
Lub jeśli możesz wydać polecenie, które wyodrębni pośredni i główny certyfikat z podstawowego certyfikatu i zapisze go w pliku ... Ja też mogę z tym żyć.
Anirban Nag 'tintinmj'
@ AnirbanNag'tintinmj 'Jeśli nie pojawia się z openssl x509poleceniem, nie sądzę, że istnieje certyfikat pośredni. (Chyba że masz jakiś błąd openssl x509).
derobert
12

tl; dr - jedna magia linijki, aby zrzucić wszystkie certyfikaty w łańcuchu

openssl s_client -showcerts -verify 5 -connect de.wikipedia.org:443 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".crt"; print >out}' && for cert in *.crt; do newname=$(openssl x509 -noout -subject -in $cert | sed -n 's/^.*CN=\(.*\)$/\1/; s/[ ,.*]/_/g; s/__/_/g; s/^_//g;p').pem; mv $cert $newname; done

Objaśnienie w 2 krokach

Aby zrzucić wszystkie certyfikaty w łańcuchu do bieżącego katalogu jako cert${chain_number}.pem:

openssl s_client -showcerts -verify 5 -connect your_host:443 < /dev/null | awk '/BEGIN/,/END/{ if(/BEGIN/){a++}; out="cert"a".pem"; print >out}' 

bonus-track, aby zmienić ich nazwy na ich wspólną nazwę:

for cert in *.pem; do newname=$(openssl x509 -noout -subject -in $cert | sed -n 's/^.*CN=\(.*\)$/\1/; s/[ ,.*]/_/g; s/__/_/g; s/^_//g;p').pem; mv $cert $newname; done
estani
źródło
Czy istnieje powód, aby wybrać rozszerzenie „.pem” kontra „.crt” jako rozszerzenie, ponieważ zmieniasz tylko ich nazwy, a nie zmieniasz format?
Kapitan Man
Nie, nie bardzo. „.pem” to format (base64 DER) „.crt” oznacza, że ​​jest to certyfikat, ale nie mówi nic o kodowaniu. Miałem zamiar uczynić go bardziej spójnym i nazwać wszystkie pem ... Ale myślę, że łatwiej jest przeczytać w jednym wierszu, aby zrozumieć, gdzie pobierany jest certyfikat (crt) i dokończyć to, czego zwykle używam w świecie Linux (pem) . Mam nadzieję, że to trochę wyjaśni ...
estani
1
Tak, wiem, że PEM to format, ale często widzę CRT i nie byłem pewien, czy to format. To faktycznie pomaga wyjaśnić, dlaczego widzę, że „crt” jest tak często używane. Dzięki :)
Kapitan Man
Wydaje się, że działa to tylko wtedy, gdy masz zaufanie do źródła. Próbuję pobrać niestandardowy urząd certyfikacji, ale pobiera on tylko pierwszy certyfikat, a nie łańcuch.
mjaggard
@mjaggard dziwne, ponieważ użyłem go dokładnie do tego przypadku. To powiedziawszy, serwer może wcale nie wysyłać głównego urzędu certyfikacji, jeśli spojrzysz na mój przykład, kiedyś pobierał 3 certyfikaty, teraz pobiera tylko 2. Zakładam, że serwer wikipedia nie wysyła roota (naprawdę nie ma punkt, jeśli go nie masz, i tak mu nie zaufasz ...). Jestem prawie pewien, że wcześniej tak nie było.
estani