是否有一种方法可以通过编程方式检查SAN SSL证书的使用者备用名称?例如,使用以下命令,我可以获得许多信息,但不是所有SAN:
openssl s_client -connect www.website.example:443
o4tp2gmn1#
要获取证书的使用者备用名称(SAN),请使用以下命令:
openssl s_client -connect website.example:443 </dev/null 2>/dev/null | openssl x509 -noout -text | grep DNS:
首先,此命令连接到我们想要的站点(website.example,SSL端口为443):openssl s_client -connect website.example:443然后用管道(|)将其输入以下命令:openssl x509 -noout -text这个函数获取证书文件并输出它的所有有趣的细节,-noout标志防止它输出证书文件本身(base64编码),这是我们不需要的,-text标志告诉它以文本形式输出证书细节。通常有一大堆我们不关心的输出(签名、发行者、扩展名等),所以我们将 that 通过管道传输到一个简单的grep中:grep DNS:由于SAN条目以DNS:开始,因此只返回包含该条目的行,去掉所有其他信息,只留下所需的信息。您可能会注意到该命令没有干净地退出;openssl s_client实际上是一个客户端,保持连接打开,等待输入。如果你想让它立即退出(例如解析shell脚本中的输出),只需将echo导入其中:
website.example
openssl s_client -connect website.example:443
|
openssl x509 -noout -text
-noout
-text
grep DNS:
DNS:
openssl s_client
echo
echo | openssl s_client -connect website.example:443 | openssl x509 -noout -text | grep DNS:
为此,您不需要openssl s_client命令,只需在openssl x509命令上添加-in MyCertificate.crt,然后再次通过grep,例如:
openssl x509
-in MyCertificate.crt
openssl x509 -noout -text -in MyCertificate.crt | grep DNS:
sr4lhrrt2#
如果您只是想“看看"SAN,grep DNS:是显而易见的解决方案。如果您希望有一个更干净的列表以便进一步处理,可以使用下面的Perl正则表达式只提取名称:@names=/\sDNS:([^\s,]+)/g例如:
@names=/\sDNS:([^\s,]+)/g
true | openssl s_client -connect example.com:443 2>/dev/null \ | openssl x509 -noout -text \ | perl -l -0777 -ne '@names=/\bDNS:([^\s,]+)/g; print join("\n", sort @names);'
它将输出以下内容:
example.com example.edu example.net example.org www.example.com www.example.edu www.example.net www.example.org
所以你可以把它传输到while read name; do echo "do stuff with $name"; done等等。或者,对于一行中的逗号分隔列表,请将join("\n",替换为join(",",(The perl的-0777开关使其一次读取整个输入,而不是逐行读取)
while read name; do echo "do stuff with $name"; done
join("\n",
join(",",
-0777
eufgjt7s3#
也可以使用捆绑的OpenSSL功能:
openssl s_client -connect website.example:443 </dev/null | openssl x509 -noout -ext subjectAltName
cotxawn74#
是否有方法以编程方式检查SAN SSL证书的备用名称?一个X509证书中可能有多个SAN。下面的代码来自OpenSSL wiki的SSL/TLS Client。它循环并打印名称。X509*是从一个函数中获取的,比如从TLS连接中获取SSL_get_peer_certificate,从内存中获取d2i_X509,或者从文件系统中获取PEM_read_bio_X509。
X509*
SSL_get_peer_certificate
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 %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); }
wz1wpwve5#
因为有些人只会得到SAN列表-每行一个:
openssl x509 -noout -text -in "${CERT_FILE}" | grep -Po 'DNS:\K[^,]+'
最好的,
5条答案
按热度按时间o4tp2gmn1#
要获取证书的使用者备用名称(SAN),请使用以下命令:
首先,此命令连接到我们想要的站点(
website.example
,SSL端口为443):openssl s_client -connect website.example:443
然后用管道(
|
)将其输入以下命令:openssl x509 -noout -text
这个函数获取证书文件并输出它的所有有趣的细节,
-noout
标志防止它输出证书文件本身(base64编码),这是我们不需要的,-text
标志告诉它以文本形式输出证书细节。通常有一大堆我们不关心的输出(签名、发行者、扩展名等),所以我们将 that 通过管道传输到一个简单的grep中:
grep DNS:
由于SAN条目以
DNS:
开始,因此只返回包含该条目的行,去掉所有其他信息,只留下所需的信息。您可能会注意到该命令没有干净地退出;
openssl s_client
实际上是一个客户端,保持连接打开,等待输入。如果你想让它立即退出(例如解析shell脚本中的输出),只需将echo
导入其中:如何直接从文件获取SAN?
为此,您不需要
openssl s_client
命令,只需在openssl x509
命令上添加-in MyCertificate.crt
,然后再次通过grep,例如:sr4lhrrt2#
如果您只是想“看看"SAN,
grep DNS:
是显而易见的解决方案。如果您希望有一个更干净的列表以便进一步处理,可以使用下面的Perl正则表达式只提取名称:
@names=/\sDNS:([^\s,]+)/g
例如:
它将输出以下内容:
所以你可以把它传输到
while read name; do echo "do stuff with $name"; done
等等。或者,对于一行中的逗号分隔列表,请将
join("\n",
替换为join(",",
(The perl的
-0777
开关使其一次读取整个输入,而不是逐行读取)eufgjt7s3#
也可以使用捆绑的OpenSSL功能:
cotxawn74#
是否有方法以编程方式检查SAN SSL证书的备用名称?
一个X509证书中可能有多个SAN。下面的代码来自OpenSSL wiki的SSL/TLS Client。它循环并打印名称。
X509*
是从一个函数中获取的,比如从TLS连接中获取SSL_get_peer_certificate
,从内存中获取d2i_X509
,或者从文件系统中获取PEM_read_bio_X509
。wz1wpwve5#
因为有些人只会得到SAN列表-每行一个:
最好的,