Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ssl 如何显示证书的主题替代名称?_Ssl_Openssl_Certificate_Ssl Certificate_X509certificate_Sed_Bash_Shell - Fatal编程技术网

Ssl 如何显示证书的主题替代名称?

Ssl 如何显示证书的主题替代名称?,ssl,openssl,certificate,ssl-certificate,x509certificate,sed,bash,shell,Ssl,Openssl,Certificate,Ssl Certificate,X509certificate,Sed,Bash,Shell,我找到的最接近的答案是使用“grep” 有没有更好的办法?我只喜欢命令行 谢谢。请注意,您可以通过添加以下选项将-text的输出限制为仅输出扩展名: -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux i、 e: 但是,您仍然需要应用一些文本解析逻辑,以仅获取主题备选名称 如果这还不够,我认为您需要编写一个小程序,使用ope

我找到的最接近的答案是使用“grep”

有没有更好的办法?我只喜欢命令行


谢谢。

请注意,您可以通过添加以下选项将
-text
的输出限制为仅输出扩展名:

-certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux
i、 e:

但是,您仍然需要应用一些文本解析逻辑,以仅获取
主题备选名称

如果这还不够,我认为您需要编写一个小程序,使用openssl库提取您要查找的特定字段。下面是一些示例程序,演示如何解析证书,包括提取扩展字段,如
主题备选名称


请注意,如果按照编程路线进行,则不必使用openssl和C。。。您可以选择您喜欢的语言和
ASN.1
解析器库,并使用它。例如,在Java中,您可以使用,以及许多其他工具。

您可以使用
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/'
获取证书数据 使用
gnutls
certtool
$gnutls cli example.com-p 443--打印证书
使用
openssl
取自

$openssl s|u client-connect example.com:443
提取证书数据
| grep-C3-idns
适用于一个简单的情况,如果您手工查看这些数据,肯定可以很好地工作。然而,证书数据是分层的,而不是面向行的(因此灰色化将是混乱的,尤其是对于ca链)

我不知道有任何x509命令行工具可以进行键值提取,我使用的大多数系统都在box上或附近有python,因此这里有一种使用python的方法,x509接口由提供。使用
cryptography
有点冗长,我不愿意将其压缩成一行代码,但使用此脚本,您可以从传递给stdin的证书中提取dns名称

#/usr/bin/env蟒蛇3
导入系统
导入cryptography.x509
导入加密。hazmat。后端
导入加密.hazmat.primitives
默认\u指纹\u哈希=cryptography.hazmat.primitives.hashes.SHA256
def_x509_san_dns_名称(证书):
“”“返回包含san dns名称的字符串列表
"""
crt_san_data=certificate.extensions.get_extension_for_oid(
cryptography.x509.oid.extensionId.SUBJECT\u可选\u名称
)
dns_name=crt_san_data.value.get_values_for_type(
cryptography.x509.DNSName
)
返回dns\u名称
def\u查找\u证书\u pem(流):
“产生大量pem证书
"""
证书\u pem=[]
开始证书=错误
对于流中的行:
如果行==b'----结束证书------\n':
开始证书=错误
证书附录(第行)
产生b“”。加入(证书\u pem)
证书\u pem=[]
如果行==b'----开始证书------\n':
begin\u certificate=True
如果是begin\U证书:
证书附录(第行)
定义转储标准证书存储系统():
“”“打印面向行的证书指纹和san dns名称
"""
对于查找证书中的证书(sys.stdin.buffer):
证书=cryptography.x509.load\u pem\u x509\u证书(
pem证书,
cryptography.hazmat.backends.default_backend()
)
证书\指纹=证书。指纹(
默认\u指纹\u哈希(),
)
证书\u指纹\u str=':'。加入(
“{:02x}”。证书中i的格式(i)
)
尝试:
对于_x509_san_dns_名称(证书)中的dns_名称:
sys.stdout.write('{}{}\n'.格式(证书\u指纹\u str,dns\u名称))
除了cryptography.x509.extensions.ExtensionNotFound之外:
sys.stderr.write({}证书没有扩展名SubjectAlternativeName\n'。格式(证书\u指纹\u str))
def main():
_dump_stdincert_san_dnsnames()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
####范例
$true | openssl s|U客户端-连接本地主机:8443 | openssl x509-noout-text | grep DNS:
深度=2 C=US,ST=NC,L=SomeCity,O=SomeCompany Security,OU=SomeOU,CN=SomeCN
验证错误:num=19:证书链中的自签名证书
完成
DNS:localhost,DNS:127.0.0.1,DNS:servername1.somedom.com,DNS:servername2.somedom.local
如何显示证书的主题替代名称

X509证书中可能有多个SAN。以下内容来自位于的OpenSSL wiki。它在名字上循环并打印出来

您可以从TLS连接的
SSL\u get\u peer\u certificate
、内存的
d2i\u X509
或文件系统的
PEM\u read\u bio\u X509
等函数中获取
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 %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);

}
void print\u san\u name(常量字符*标签,X509*常量证书)
{
int成功=0;
通用名称*名称=空;
无符号字符*utf8=NULL;
做
{
如果(!cert)中断;/*失败*/
name=X509\u get\u ext\u d2i(证书,NID\u主题\u alt\u名称,0,0);
如果(!name)中断;
int i=0,count=sk\u GENERAL\u NAME\u num(名称);
如果(!count)中断;/*失败*/
对于(i=0;i类型)
{
int len1=0,len2=-1;
len1=ASN1\u字符串到\u UTF8(&UTF8,条目->d.dNSName);
如果(utf8){
len2=(int)strlen((const char*)utf8);
}
if(len1!=len2){
fprintf(strerr,“Strlen和ASN1_字符串大小不匹配(嵌入null?)%d vs
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/'
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);

}
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)
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 )
         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/^\( *\)\(.*\), /\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 ) )
         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
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;
  }'
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; }'
openssl x509 -in /path/to/x509/cert -noout -text|grep -oP '(?<=DNS:|IP Address:)[^,]+'|sort -uV
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
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}'
android.clients.google.com
android.com
developer.android.google.cn
g.co
goo.gl
...
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>
openssl x509 -noout -ext subjectAltName -in cert.pem
➤ 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

➤