it-swarm.com.de

Wie wird der alternative Antragstellername eines Zertifikats angezeigt?

Die beste Antwort, die ich gefunden habe, ist "grep".

> openssl x509 -text -noout -in cert.pem | grep DNS

Gibt es einen besseren Weg, dies zu tun? Ich ziehe nur die Kommandozeile vor.

Vielen Dank.

41
user180574

Beachten Sie, dass Sie die Ausgabe von -text auf nur die Erweiterungen beschränken können, indem Sie die folgende Option hinzufügen:

-certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux

d.h.

openssl x509 -text -noout -in cert.pem \
  -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux

Sie müssen jedoch immer noch eine Textanalyse-Logik anwenden, um nur den Subject Alternative Name zu erhalten.

Wenn dies nicht ausreicht, müssen Sie ein kleines Programm schreiben, das die openssl-Bibliothek verwendet, um das gewünschte Feld zu extrahieren. Hier einige Beispielprogramme, die zeigen, wie ein Zertifizierer analysiert wird, einschließlich des Extrahierens von Erweiterungsfeldern wie Subject Alternative Name

https://zakird.com/2013/10/13/certificate-parsing-with-openssl

Beachten Sie, dass Sie nicht OpenSL und C verwenden müssen, wenn Sie die Programmierroute wählen. Sie können Ihre bevorzugte Sprache und die ASN.1 Parser-Bibliothek auswählen und diese verwenden. In Java können Sie beispielsweise http://jac-asn1.sourceforge.net/ und viele andere verwenden.

31
Raman

Entnommen aus https://stackoverflow.com/a/13128918/1695680

$ true | openssl s_client -connect example.com:443 | openssl x509 -noout -text | grep DNS:

Beispiel

$ true | openssl s_client -connect localhost:8443 | openssl x509 -noout -text | grep DNS:
depth=2 C = US, ST = NC, L = SomeCity, O = SomeCompany Security, OU = SomeOU, CN = SomeCN
verify error:num=19:self signed certificate in certificate chain
DONE
                DNS:localhost, DNS:127.0.0.1, DNS:servername1.somedom.com, DNS:servername2.somedom.local
18
ThorSummoner

Es gibt meine Lösung (mit openssl und sed ):

bash zuerst

sed -ne '
    s/^\( *\)Subject:/\1/p;
    /X509v3 Subject Alternative Name/{
        N;
        s/^.*\n//;
      :a;
        s/^\( *\)\(.*\), /\1\2\n\1/;
        ta;
        p;
        q;
    }' < <(openssl x509 -in cert.pem -noout -text)

könnte geschrieben werden:

sed -ne 's/^\( *\)Subject:/\1/p;/X509v3 Subject Alternative Name/{
    N;s/^.*\n//;:a;s/^\( *\)\(.*\), /\1\2\n\1/;ta;p;q; }' < <(
    openssl x509 -in cert.pem -noout -text )

und könnte so etwas darstellen:

         CN=www.example.com
                DNS:il0001.sample.com
                DNS:example.com
                DNS:demodomain.com
                DNS:testsite.com
                DNS:www.il0001.sample.com
                DNS:www.il0001.sample.com.vsite.il0001.sample.com
                DNS:www.example.com
                DNS:www.example.com.vsite.il0001.sample.com
                DNS:www.demodomain.com
                DNS:www.demodomain.com.vsite.il0001.sample.com
                DNS:www.testsite.com
                DNS:www.testsite.com.vsite.il0001.sample.com

Gleiches für Live-Server

sed -ne 's/^\( *\)Subject:/\1/p;/X509v3 Subject Alternative Name/{
    N;s/^.*\n//;:a;s/^\( *\)\(.*\), /\1\2\n\1/;ta;p;q; }' < <(
    openssl x509 -noout -text -in <(
        openssl s_client -ign_eof 2>/dev/null <<<$'HEAD / HTTP/1.0\r\n\r' \
            -connect google.com:443 ) )

Mai Ausgabe:

         C=US, ST=California, L=Mountain View, O=Google Inc, CN=*.google.com
                DNS:*.google.com
                DNS:*.Android.com
                DNS:*.appengine.google.com
                DNS:*.cloud.google.com
                DNS:*.gcp.gvt2.com
                DNS:*.google-analytics.com
                DNS:*.google.ca
                DNS:*.google.cl
                DNS:*.google.co.in
                DNS:*.google.co.jp
                DNS:*.google.co.uk
                DNS:*.google.com.ar
                DNS:*.google.com.au
                DNS:*.google.com.br
                DNS:*.google.com.co
                DNS:*.google.com.mx
                DNS:*.google.com.tr
                DNS:*.google.com.vn
                DNS:*.google.de
                DNS:*.google.es
                DNS:*.google.fr
                DNS:*.google.hu
                DNS:*.google.it
                DNS:*.google.nl
                DNS:*.google.pl
                DNS:*.google.pt
                DNS:*.googleadapis.com
                DNS:*.googleapis.cn
                DNS:*.googlecommerce.com
                DNS:*.googlevideo.com
                DNS:*.gstatic.cn
                DNS:*.gstatic.com
                DNS:*.gvt1.com
                DNS:*.gvt2.com
                DNS:*.metric.gstatic.com
                DNS:*.Urchin.com
                DNS:*.url.google.com
                DNS:*.youtube-nocookie.com
                DNS:*.youtube.com
                DNS:*.youtubeeducation.com
                DNS:*.ytimg.com
                DNS:Android.clients.google.com
                DNS:Android.com
                DNS:developer.Android.google.cn
                DNS:g.co
                DNS:goo.gl
                DNS:google-analytics.com
                DNS:google.com
                DNS:googlecommerce.com
                DNS:Urchin.com
                DNS:www.goo.gl
                DNS:youtu.be
                DNS:youtube.com
                DNS:youtubeeducation.com

POSIX Shell jetzt

Da < <(...) ein bashism ist, muss derselbe Befehl geschrieben werden:

openssl x509 -in cert.pem -noout -text | sed -ne '
  s/^\( *\)Subject:/\1/p;
  /X509v3 Subject Alternative Name/{
      N;
      s/^.*\n//;
    :a;
      s/^\( *\)\(.*\), /\1\2\n\1/;
      ta;
      p;
      q;
  }'

und

printf 'HEAD / HTTP/1.0\r\n\r\n' |
    openssl s_client -ign_eof 2>/dev/null -connect google.com:443 |
    openssl x509 -noout -text |
    sed -ne 's/^\( *\)Subject:/\1/p;/X509v3 Subject Alternative Name/{
        N;s/^.*\n//;:a;s/^\( *\)\(.*\), /\1\2\n\1/;ta;p;q; }'
10
F. Hauri

Neuere Versionen von openssl verfügen über die Option '-ext', mit der Sie nur den Eintrag subjectAltName drucken können. Benutze 'OpenSSL 1.1.1b' unter Debian 9.9

openssl x509 -noout -ext subjectAltName -in cert.pem

Sie müssen die Ausgabe jedoch noch analysieren.

Die Änderung wurde in https://github.com/openssl/openssl/issues/3932 vorgenommen

4
Ely

Sehr einfache Lösung mit grep

openssl x509 -in /path/to/x509/cert -noout -text|grep -oP '(?<=DNS:|IP Address:)[^,]+'|sort -uV

Für das Google-Zertifikat wird Folgendes ausgegeben:

Android.clients.google.com
Android.com
developer.Android.google.cn
g.co
goo.gl
google.com
googlecommerce.com
google-analytics.com
hin.com
Urchin.com
www.goo.gl
youtu.be
youtube.com
youtubeeducation.com
*.Android.com
*.appengine.google.com
*.cloud.google.com
*.gcp.gvt2.com
*.googleadapis.com
*.googleapis.cn
*.googlecommerce.com
*.googlevideo.com
*.google.ca
*.google.cl
*.google.com
*.google.com.ar
*.google.com.au
*.google.com.br
*.google.com.co
*.google.com.mx
*.google.com.tr
*.google.com.vn
*.google.co.in
*.google.co.jp
*.google.co.uk
*.google.de
*.google.es
*.google.fr
*.google.hu
*.google.it
*.google.nl
*.google.pl
*.google.pt
*.gstatic.cn
*.gstatic.com
*.gvt1.com
*.gvt2.com
*.metric.gstatic.com
*.Urchin.com
*.url.google.com
*.youtubeeducation.com
*.youtube.com
*.ytimg.com
*.google-analytics.com
*.youtube-nocookie.com
3
ThinGuy

Sie können awk verwenden, um näher an das SAN zu gelangen, indem Sie die obigen Optionen in die Anweisung awk leiten:

openssl x509 -in mycertfile.crt -text -noout \
  -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_aux \
 | awk '/X509v3 Subject Alternative Name/','/X509v3 Basic Constraints/'
1
RandomW

Eine verbesserte awk-basierte Lösung (Hat-Tip: @RandomW): 

openssl x509 -in certfile -text -noout \
  -certopt no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux \
| awk '/X509v3 Subject Alternative Name:/ {san=1;next} 
      san && /^ *X509v3/ {exit} 
      san { sub(/DNS:/,"",$1);print $1}'

Dies gibt eine Liste aus, ebenso wie die Lösungen grep und sed. Der Unterschied besteht darin, dass die Ortung der Informationen genauer gesteuert wird. Sollte sich das Ausgabeformat ändern, ist diese Version robuster und kann die Änderungen besser handhaben. Es wird nur der Text zwischen "Subject Alternative Name" und dem nächsten Abschnitt "X509v3" ausgedruckt, und der gesamte optionale Text "DNS:" wird entfernt.

Android.clients.google.com
Android.com
developer.Android.google.cn
g.co
goo.gl
...
0
Otheus

Hinzufügen einer Python-Alternative . Voraussetzung ist, dass Sie eine Zeichenfolge mit den Datensätzen "DNS:" haben.

# Fetch the certificate details (subprocess, OpenSSL module, etc)
# dnsstring contains the "DNS:" line of the "openssl" output
# Example of how to get the string of DNS names from a string output of the certificate
for idx, line in enumerate(certoutput.split()):
    if ' X509v3 Authority Key Identifier:' in line:
        dnsstring = certoutput.split()[idx + 1]

# Get a list
[x.replace('DNS:', '').replace(',', '') for x in dnsstring]

# Format to a comma separated string
', '.join([x.replace('DNS:', '').replace(',', '') for x in dnsstring])

Ein Befehlszeilenbeispiel:

true | \
  openssl s_client -showcerts -connect google.com:443 2>/dev/null | \
  openssl x509 -noout -text 2>/dev/null | grep " DNS:" | \
  python -c"import sys; print ', '.join([x.replace('DNS:', '').replace(',', '') for x in sys.stdin.readlines()[0].split()])"

Ausgabe:

*.google.com, *.Android.com, <etc>
0
sastorsl

Vielleicht ist das genug:

openssl x509 -in cert.pem -noout -text -certopt ca_default,no_sigdump
0
NOZUONOHIGH

Wie wird der alternative Antragstellername eines Zertifikats angezeigt?

Ein X509-Zertifikat kann mehrere SANs enthalten. Folgendes ist aus dem OpenSSL-Wiki unter SSL/TLS Client . Es durchläuft die Namen und druckt sie.

Sie erhalten X509* von einer Funktion wie SSL_get_peer_certificate von einer TLS-Verbindung, d2i_X509 aus dem Speicher oder PEM_read_bio_X509 aus dem Dateisystem.

void print_san_name(const char* label, X509* const cert)
{
    int success = 0;
    GENERAL_NAMES* names = NULL;
    unsigned char* utf8 = NULL;

    do
    {
        if(!cert) break; /* failed */

        names = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0 );
        if(!names) break;

        int i = 0, count = sk_GENERAL_NAME_num(names);
        if(!count) break; /* failed */

        for( i = 0; i < count; ++i )
        {
            GENERAL_NAME* entry = sk_GENERAL_NAME_value(names, i);
            if(!entry) continue;

            if(GEN_DNS == entry->type)
            {
                int len1 = 0, len2 = -1;

                len1 = ASN1_STRING_to_UTF8(&utf8, entry->d.dNSName);
                if(utf8) {
                    len2 = (int)strlen((const char*)utf8);
                }

                if(len1 != len2) {
                    fprintf(stderr, "  Strlen and ASN1_STRING size do not match (embedded null?): %d vs %d\n", len2, len1);
                }

                /* If there's a problem with string lengths, then     */
                /* we skip the candidate and move on to the next.     */
                /* Another policy would be to fails since it probably */
                /* indicates the client is under attack.              */
                if(utf8 && len1 && len2 && (len1 == len2)) {
                    fprintf(stdout, "  %s: %s\n", label, utf8);
                    success = 1;
                }

                if(utf8) {
                    OPENSSL_free(utf8), utf8 = NULL;
                }
            }
            else
            {
                fprintf(stderr, "  Unknown GENERAL_NAME type: %d\n", entry->type);
            }
        }

    } while (0);

    if(names)
        GENERAL_NAMES_free(names);

    if(utf8)
        OPENSSL_free(utf8);

    if(!success)
        fprintf(stdout, "  %s: <not available>\n", label);

}
0
jww