Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.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
Python使用ssl.getpeercert()从URL获取公共名称_Python_Ssl_Https - Fatal编程技术网

Python使用ssl.getpeercert()从URL获取公共名称

Python使用ssl.getpeercert()从URL获取公共名称,python,ssl,https,Python,Ssl,Https,我正在尝试获取证书颁发者信息(通用名称),但链接中的代码不能用于某些URL 例如,我尝试了主机名“cds.ca”,它说 但我仍然可以使用Internet Explorer(*.cds.ca)获得通用名称 所以我想我应该使用我自己的证书(.cer)而不是使用getpeercert(),那么我应该如何更改该行 或者,是否有其他方法可以使用我自己的证书文件实现CN?如果您只想获取CN或其他证书详细信息,无论证书验证是否成功,都必须禁用验证。不幸的是,如果证书验证被禁用,简单的sock.getpeer

我正在尝试获取证书颁发者信息(通用名称),但链接中的代码不能用于某些URL

例如,我尝试了主机名“cds.ca”,它说

但我仍然可以使用Internet Explorer(*.cds.ca)获得通用名称

所以我想我应该使用我自己的证书(.cer)而不是使用getpeercert(),那么我应该如何更改该行


或者,是否有其他方法可以使用我自己的证书文件实现CN?

如果您只想获取CN或其他证书详细信息,无论证书验证是否成功,都必须禁用验证。不幸的是,如果证书验证被禁用,简单的
sock.getpeercert()
在设计上只会返回一个空字典。这就是为什么必须使用
sock.getpeercert(True)
来获取证书的二进制表示形式,并使用OpenSSL.crypto从中提取CN:

import socket
import ssl
import OpenSSL.crypto as crypto

dst = ('cds.ca',443)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(dst)

# upgrade the socket to SSL without checking the certificate
# !!!! don't transfer any sensitive data over this socket !!!!
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = ctx.wrap_socket(s, server_hostname=dst[0])

# get certificate
cert_bin = s.getpeercert(True)
x509 = crypto.load_certificate(crypto.FILETYPE_ASN1,cert_bin)
print("CN=" + x509.get_subject().CN)

您是在询问如何确保证书验证成功以获取CN,还是在证书验证失败的情况下如何获取CN?两者都可以。我尝试了后一种方法(查找了许多关于忽略证书验证的问题),但我失败了:(从网站上获取CN(与Internet Explorer显示的相同)是我想要的全部。这是我一直在搜索的答案。它有效,即使证书已过期或由于其他几个原因无效。(不是所有原因,但大多数。)注意:在连接之前,您可能需要使用
s.settimeout(5)
提供一个超时,否则如果无法访问主机,套接字将永远阻塞。
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)
import socket
import ssl
import OpenSSL.crypto as crypto

dst = ('cds.ca',443)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(dst)

# upgrade the socket to SSL without checking the certificate
# !!!! don't transfer any sensitive data over this socket !!!!
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
s = ctx.wrap_socket(s, server_hostname=dst[0])

# get certificate
cert_bin = s.getpeercert(True)
x509 = crypto.load_certificate(crypto.FILETYPE_ASN1,cert_bin)
print("CN=" + x509.get_subject().CN)