ssl – Как отобразить альтернативное имя субъекта сертификата? –

10 ответов

Лучший ответ

Обратите внимание, что вы можете ограничить вывод -text только расширениями, добавив следующую опцию:

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

Я.:

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

Однако вам все равно придется применить некоторую логику синтаксического анализа текста, чтобы получить только Subject Alternative Name.

Если этого недостаточно, я думаю, вам нужно написать небольшую программу, которая использует библиотеку openssl для извлечения конкретного поля, которое вы ищете. Вот несколько примеров программ, которые показывают, как анализировать сертификат, включая извлечение полей расширения, таких как Subject Alternative Name:

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

Обратите внимание, что вам не обязательно использовать openssl и C, если вы идете по пути программирования … вы можете выбрать свой любимый язык и библиотеку синтаксического анализатора ASN.1 и использовать ее. Например, в Java вы можете использовать http://jac-asn1.sourceforge.net/, и много других.

Вот как мы можем это сделать с помощью awk.

'/Subject: C=/{printf $NF"n"} соответствует любой строке с шаблоном /Subject: C=, а {printf $NF"n"} просто печатает последнее поле с новой строкой.

/DNS:/{x=gsub(/ *DNS:/, ""); printf "SANS=" $0"n"} соответствует строке с шаблоном DNS:. gsub используется для замены ненужных DNS: перед каждым fqdn. printf "SANS="$0"n" печатает всю строку с новой строкой.

➤ echo | openssl s_client -connect google.com:443 2>&1 | openssl x509 -noout -text |  awk '/Subject: C=/{printf $NF"n"} /DNS:/{x=gsub(/ *DNS:/, ""); printf "SANS=" $0"n"}'
CN=*.google.com
SANS=*.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.crowdsource.google.com,*.g.co,*.gcp.gvt2.com,*.gcpcdn.gvt1.com,*.ggpht.cn,*.gkecnapps.cn,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleadapis.com,*.googleapis.cn,*.googlecnapps.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.cn,*.gstatic.com,*.gstaticcnapps.cn,*.gvt1.com,*.gvt2.com,*.metric.gstatic.com,*.urchin.com,*.url.google.com,*.wear.gkecnapps.cn,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.youtubekids.com,*.yt.be,*.ytimg.com,android.clients.google.com,android.com,developer.android.google.cn,developers.android.google.cn,g.co,ggpht.cn,gkecnapps.cn,goo.gl,google-analytics.com,google.com,googlecnapps.cn,googlecommerce.com,source.android.google.cn,urchin.com,www.goo.gl,youtu.be,youtube.com,youtubeeducation.com,youtubekids.com,yt.be

➤

Добавление альтернативы Python. Обязательным условием является наличие строки с записями «DNS:».

Получите сведения о сертификате (подпроцесс, модуль OpenSSL и т. Д.). Dnsstring содержит строку «DNS:» вывода «openssl». Пример того, как получить строку DNS-имен из текстового вывода сертификата.

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])

Пример командной строки:

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()])"

Выход:

*.google.com, *.android.com, <etc>

Улучшенное решение на основе awk (подсказка: @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}'

Это распечатает список, как и решения grep и sed, которые также можно найти здесь. Разница в том, что существует более жесткий контроль того, где находится информация. Если формат вывода когда-либо изменится, эта версия станет более надежной и лучше перенесет изменения. Распечатывается только текст между «Альтернативным именем субъекта» и следующим разделом «X509v3», а весь необязательный предшествующий текст «DNS:» удаляется.

android.clients.google.com
android.com
developer.android.google.cn
g.co
goo.gl
...

Вы можете использовать awk, чтобы приблизиться к SAN, передав указанные выше параметры в оператор awk:

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/'

Как отобразить альтернативное имя субъекта сертификата?

В сертификате X509 может быть несколько сетей SAN. Следующее взято из вики OpenSSL по адресу SSL / TLS Client. Он перебирает имена и печатает их.

Про сертификаты:  Подарочный сертификат на уборку от компании Clean House

Вы получаете X509* из такой функции, как SSL_get_peer_certificate из TLS-соединения, d2i_X509 из памяти или PEM_read_bio_X509 из файловой системы.

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 %dn", 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: %sn", label, utf8);
                    success = 1;
                }

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

    } while (0);

    if(names)
        GENERAL_NAMES_free(names);

    if(utf8)
        OPENSSL_free(utf8);

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

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

Может быть написано:

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

И может отобразить что-то вроде:

         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

То же самое для живого сервера

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

Может выходить:

         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 прямо сейчас

Поскольку < <(...) – это bashism , необходимо написать ту же команду:

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

А также

printf 'HEAD / HTTP/1.0rnrn' |
    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/^( *)(.*), /12n1/;ta;p;q; }'

Posix shell прямо сейчас

Поскольку < <(…) – это bashism , необходимо написать ту же команду:

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

А также

Ssl – альтернативное имя субъекта отсутствует в сертификате –

Лучший ответ

Для всех, кто не любит редактировать общесистемный openssl.conf, есть собственная опция CLI openssl для добавления SAN в .crt из .csr. Все, что вам нужно использовать, это параметры интерфейса командной строки openssl -extfile и -extensions.

Вот пример:

openssl x509 -req -days 3650 -in alice.csr -signkey aliceprivate.key -out alice.crt -extfile alice-csr.conf -extensions v3_req

Для этого требуется файл alice-csr.conf, который выглядит следующим образом (введите соответствующие данные) и который использовался для генерации .csr с помощью команды openssl req -new -key aliceprivate.key -out alice.csr -config alice-csr.conf:

[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no

[req_distinguished_name]
C = DE
ST = Thuringia
L = Erfurt
O = Alice Corp
OU = Team Foo
CN = server-alice

[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = server-alice
DNS.2 = localhost

Имейте в виду, что параметр -extensions v3_req соответствует разделу [v3_req] в файле alice-csr.conf, где вы определяете альтернативные имена субъектов, то есть домены, которым вы хотите выдать свой сертификат.

Про сертификаты:  казахский словарь банковских терминов Банк терминдеріні~ орысша~аза~ша с~здігі Дай

Поскольку я всегда ценю полностью понятные примеры, в которых можно воспроизвести каждый шаг, я создал пример проекта с микросервисами Spring Boot: https://github.com/jonashackt/spring-boot-rest-clientcertificates-docker-compose

Недопустимый самозаверяющий сертификат ssl – " отсутствует альтернативное имя субъекта" | блог о программировании

on MAC
начиная с версии chrome 67.0.3396.99 мой самозаверяющий сертификат перестал работать.

регенерация со всем, что здесь написано, не сработала.

обновление

был шанс подтвердить, что мой подход работает сегодня :). Если это не работает для вас убедитесь, что вы используете этот подход

v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = <specify-the-same-common-name-that-you-used-while-generating-csr-in-the-last-step>
$

скопировать из здесь
https://ksearch.wordpress.com/2021/08/22/generate-and-import-a-self-signed-ssl-certificate-on-mac-osx-sierra/

ОБНОВЛЕНИЯ

наконец-то смог увидеть зеленый Безопасный только тогда, когда удалены мой сертификат от система и добавил на local брелок. (если есть один-бросьте его первым). не уверен, что это имеет значение, но в моем случае я загрузил сертификат через chrome и проверил эта дата создания сегодня-так что это тот, который я только что создал.

надеюсь, это будет полезно для кого-то потратить день на это.

никогда не обновляйте chrome!

Номенклатура сертификатов

Давайте рассмотрим, какие сертификаты X.509 встречаются в природе, если рассматривать их по расположению в

пищевой

цепочке доверия.

По степени

крутизны

дороговизны и надежности сертификаты делятся на 3 вида:

DVOVEV

Откуда берутся сертификаты?

Еще совсем недавно было всего 2 способа заполучить X.509 сертификат, но времена меняются и с недавнего времени есть и третий путь.

  1. Создать свой собственный сертификат и самому же его подписать. Плюсы — это бесплатно, минусы — сертификат будет принят лишь вами и, в лучшем случае, вашей организацией.

    not trusted

  2. Приобрести сертификат в УЦ. Это будет стоить денег в зависимости от различных его характеристик и возможностей, указанных выше.
  3. Получить бесплатный сертификат LetsEncrypt, доступны только самые простые DV сертификаты.

Для первого сценария достаточно пары команд и чтобы 2 раза не вставать создадим сертификат с алгоритмом эллиптических кривых. Первым шагом нужно создать закрытый ключ. Считается, что шифрование с алгоритмом эллиптических кривых дает больший выхлоп, если измерять в тактах CPU, либо байтах длины ключа. Поддержка ECC не определена однозначно в TLS < 1.2.

openssl ecparam -name secp521r1 -genkey -param_enc explicit -out private-key.pem

Далее, создает CSR — запрос на подписание сертификата.

openssl req -new -sha256 -key private.key -out server.csr -days 730

И подписываем.

openssl x509 -req -sha256 -days 365 -in server.csr -signkey private.key -out public.crt

Результат можно посмотреть командой:

openssl x509 -text -noout -in public.crt

Openssl имеет огромное количество опций и команд. Man страница не очень полезна, справочник удобнее использовать так:

openssl -help
openssl x509 -help
openssl s_client -help

Ровно то же самое можно сделать с помощью java утилиты keytool.

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

Следует серия вопросов, чтобы было чем запомнить поля owner и issuer

What is your first and last name?
What is the name of your organizational unit?
What is the name of your organization?
What is the name of your City or Locality?
What is the name of your State or Province?
What is the two-letter country code for this unit?
Is CN=Johnnie Walker, OU=Unknown, O=Unknown, L=Moscow, ST=Moscow, C=RU correct?

Конвертируем связку ключей из проприетарного формата в PKCS12.

keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12

Смотрим на результат:

keytool -list -v -alias selfsigned -storepass password -keystore keystore.jks
Alias name: selfsigned
Creation date: 20.01.2021
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Johnnie Walker, OU=Unknown, O=Unknown, L=Moscow, ST=Moscow, C=RU
Issuer: CN=Johnnie Walker, OU=Unknown, O=Unknown, L=Moscow, ST=Moscow, C=RU
Serial number: 1f170cb9
Valid from: Sat Jan 20 18:33:42 MSK 2021 until: Tue Jan 15 18:33:42 MSK 2021
Certificate fingerprints:
     MD5:  B3:E9:92:87:13:71:2D:36:60:AD:B5:1F:24:16:51:05
     SHA1: 26:08:39:19:31:53:C5:43:1E:ED:2E:78:36:43:54:9B:EA:D4:EF:9A
     SHA256: FD:42:C9:6D:F6:2A:F1:A3:BC:24:EA:34:DC:12:02:69:86:39:F1:FC:1B:64:07:FD:E1:02:57:64:D1:55:02:3D

Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 30 95 58 E3 9E 76 1D FB   92 44 9D 95 47 94 E4 97  0.X..v...D..G...
0010: C8 1E F1 92                                        ....
]
]

Значению ObjectId: 2.5.29.14 соответствует определение ASN.1, согласно RFC 3280 оно всегда non-critical. Точно так же можно узнать смысл и возможные значения других ObjectId, которые присутствуют в сертификате X.509.

subjectKeyIdentifier EXTENSION ::= {
    SYNTAX SubjectKeyIdentifier
    IDENTIFIED BY id-ce-subjectKeyIdentifier
}

SubjectKeyIdentifier ::= KeyIdentifier

Словарный запас

Определение X.509 сертификатов есть в архиве ITU-T

Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signatureValue       BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
     version         [0]  EXPLICIT Version DEFAULT v1,
     serialNumber         CertificateSerialNumber,
     signature            AlgorithmIdentifier,
     issuer               Name,
     validity             Validity,
     subject              Name,
     subjectPublicKeyInfo SubjectPublicKeyInfo,
     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3

Для того, чтобы досконально понять обозначения и синтаксис, придется читать спеки X.680 редакции 2008 г., где есть полное описание ASN.1. В понятиях ASN.1SEQUENCE обозначает примерно то же самое, что и struct в Си. Это может сбить с толку, ведь по семантике оно должно было соответствовать скорее массиву. И тем не менее.

Про сертификаты:  Email: Exim и Dovecot – настройка SSL/TLS от Let’s Encrypt

Стандарт X.690 определяет следующие правила кодирования структур данных, созданных в соответствии с ASN.1: BER (Basic Encoding Rules), CER (Canonical Encoding Rules), DER (Distinguished Encoding Rules). Есть даже XER (XML Encoding Rules), который на практике мне никогда не встречался.

Да, но для чего нужны сертификаты X.509, которые доставляют столько головной боли? Первая и основная функция сертификатов X.509 — служить хранилищем открытого или публичного ключа PKI (public key infrastructure). К этой функции нареканий нет, а вот со второй не все так однозначно.

Вторая функция сертификатов X.509 заключается в том, чтобы предъявитель сего был принят человеком, либо программой в качестве истинного владельца некоего цифрового актива: доменного имени, веб сайта и пр. Это получается по-разному, далеко не все сертификаты имеют высокую ликвидность, если пользоваться финансовой терминологией.

Сценарий №1 — найти следующего в связке

Связка сертификатов — Объединение нескольких X.509 сертификатов в один файл, чаще всего в формате PEM. Связка передается по сети в момент протокола рукопожатия SSL/TLS.

Самый сок начинается, когда имеете дело со связкой сертификатов, a. k. a certificate chain. Часто просматривая лапшу в связке ключей jks непросто понять как найти родительский сертификат, когда там россыпь новых и старых сертификатов на несколько доменных имен.

Оцените статью
Мой сертификат
Добавить комментарий