it-swarm.com.de

So überprüfen Sie alternative Antragstellernamen für ein SSL / TLS-Zertifikat

Gibt es eine Möglichkeit, die alternativen Antragstellernamen eines SAN SSL-Zertifikats programmgesteuert zu überprüfen?

Wenn ich zum Beispiel den folgenden Befehl verwende, kann ich viele Informationen abrufen, aber nicht alle SANs:

openssl s_client -connect www.website.com:443 

Vielen Dank!

51
JoeSlav

Verwenden Sie den folgenden Befehl, um die alternativen Antragstellernamen (Subject Alternative Names, SAN) für ein Zertifikat abzurufen:

openssl s_client -connect website.com:443 | openssl x509 -noout -text | grep DNS:

Dieser Befehl stellt zunächst eine Verbindung zu der gewünschten Site her (website.com, Port 443 für SSL):

openssl s_client -connect website.com:443

Dann leite (|) Das in diesen Befehl:

openssl x509 -noout -text

Dies nimmt die Zertifikatsdatei und gibt alle wichtigen Details aus. Das Flag -noout Verhindert, dass die (base64-codierte) Zertifikatdatei selbst ausgegeben wird, die wir nicht benötigen. Das Flag -text Weist es an, die Zertifikatsdetails in Textform auszugeben.

Normalerweise gibt es eine ganze Reihe von Ausgaben (Signatur, Herausgeber, Erweiterungen usw.), die uns egal sind, also leiten wir dass in ein einfaches grep:

grep DNS:

Da die SAN Einträge mit DNS: Beginnen, werden nur die Zeilen zurückgegeben, die diese enthalten. Alle anderen Informationen werden entfernt, und die gewünschten Informationen bleiben erhalten.

Möglicherweise stellen Sie fest, dass der Befehl nicht ordnungsgemäß beendet wird. openssl s_client Fungiert tatsächlich als Client und lässt die Verbindung offen und wartet auf Eingaben. Wenn Sie möchten, dass es sofort beendet wird (z. B. um die Ausgabe in einem Shell-Skript zu analysieren), leiten Sie einfach echo hinein:

echo | openssl s_client -connect website.com:443 | openssl x509 -noout -text | grep DNS:

Wie bekomme ich das SAN direkt aus einer Datei?

Dafür benötigen Sie nicht den Befehl openssl s_client. Fügen Sie einfach -in MyCertificate.crt Zum Befehl openssl x509 Hinzu und leiten Sie erneut grep durch, z.

openssl x509 -noout -text -in MyCertificate.crt | grep DNS:
85
JoeSlav

Gibt es eine Möglichkeit, die alternativen Namen eines SAN SSL-Zertifikats programmgesteuert zu überprüfen?

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

Du erhältst das X509* aus 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);

}
2
jww