Python SSL证书根据通用名称检查主机名

时间:2016-06-17 08:26:34

标签: python python-3.x ssl

我想根据SSL证书检查主机名和端口。我创建了这个函数:

@staticmethod
def common_name_check(hostname, port):
    try:
        ctx = ssl.create_default_context()
        s = ctx.wrap_socket(socket.socket(), server_hostname=hostname)
        s.connect((hostname, int(port)))
        cert = s.getpeercert()
        ssl.match_hostname(cert, hostname)
    except Exception as e:
        exc_type, exc_obj, exc_tb = sys.exc_info()
        fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
        print(exc_type, fname, exc_tb.tb_lineno)
        return False
    else:
        return True

我的问题是:证书过期后,验证失败。但例外情况不明确:

<class 'ssl.SSLError'>

我不知道错误是由于证书过期还是错误的通用名称

我怎样才能检查主机名/端口是否对证书有效?

2 个答案:

答案 0 :(得分:0)

完全。 SSL错误太通用了。我也在努力解决这个问题。所以你可能想要查看这个链接。

Verifying SSL certificates in python

以下是仅代码答案。

from OpenSSL import SSL
from socket import socket

context = SSL.Context(SSL.TLSv1_METHOD) # Use TLS Method
context.set_options(SSL.OP_NO_SSLv2) # Don't accept SSLv2
context.set_verify(SSL.VERIFY_NONE, callback)
context.load_verify_locations(ca_file, ca_path)

host = "google.com"
port = 443    #ssl
sock = socket()
ssl_sock = SSL.Connection(context, sock)
ssl_sock.connect((host, port))
ssl_sock.do_handshake()

def callback(self, conn, certificate, err, depth, valid):
    # err here is the error code ([List of error codes and what they mean][2].
    if err == 62:
        print("HOSTNAME MISMATCH!!!")

答案 1 :(得分:0)

我正在使用类似的东西。 certfile是PEM格式。 不太一样,因为我正在与证书文件进行比较。

# Check if the certificate commonName is a match to MYSTRING
certpath = 'c:\cert.cer'
from cryptography import x509
from cryptography.hazmat.backends import default_backend
cfile = open(certpath,"r")
cert_file = cfile.read()
cert = x509.load_pem_x509_certificate(cert_file, default_backend())
for fields in cert.subject:
    current = str(fields.oid)
    if "commonName" in current:
        if fields.value == MYSTRING:
            print 'certificate (' + fields.value + ') matches'
        else:
            print 'certificate (' + fields.value + ') does NOT match'