Python ssl:check_hostname中的IP地址

发布时间:2020-07-07 14:28

Python3 ssl库可以使用IP地址,而不使用证书中的主机名吗?

假设我尝试连接到服务器:

ip = '192.168.0.99'
context = ssl.create_default_context(cafile='ca.crt')
with socket.create_connection((ip, 443)) as sock:
  with context.wrap_socket(sock, server_hostname=ip) as ssock:
    print(ssock.version())

运行它时出现错误:

SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)

IP地址192.168.0.99也被写入证书的“通用名称”和“主题替代名称”。

$ openssl x509 -in san.crt  -noout  -text | grep -B 1 192.168.0.99
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = RU, ST = MSK, O = Internet Widgits Pty Ltd, OU = example, CN = 192.168.0.99
--
            Not After : Jul  4 21:31:32 2030 GMT
        Subject: C = RU, ST = MSK, O = Internet Widgits Pty Ltd, OU = example, CN = 192.168.0.99
--
            X509v3 Subject Alternative Name:
                IP Address:192.168.0.99
回答1

SSLCertVerificationError:[SSL:CERTIFICATE_VERIFY_FAILED]证书验证失败:无法获取本地发行者证书(_ssl.c:1056)

错误并非与主机名不匹配证书有关,而是与找不到证书的本地受信任颁发者有关。

context = ssl.create_default_context(cafile='ca.crt')

我认为您的意图是ca.crtsan.crt的发行者。但是根据您从证书中显示的内容,它看起来像是自签名证书(主题和颁发者是相同的),而不是由ca.crt签名。