ssl.SSLError:[SSL:CERTIFICATE_VERIFY_FAILED]证书验证失败,Python套接字,ssl,gmail smtp连接

问题描述:

我想使用安全套接字连接到gmail SMTP服务器。我通过使用我的浏览器 - Firefox(我只需打开gmail.com页面,然后使用浏览器导出证书按钮导出证书)下载mail.google.com.crt cert文件。ssl.SSLError:[SSL:CERTIFICATE_VERIFY_FAILED]证书验证失败,Python套接字,ssl,gmail smtp连接

但是,它似乎有一个问题,我不知道为什么。当我将mail.google.com.crt更改为GeoTrustGlobalCA.pem(我发现它在某处在线)它工作(没有显示错误)。我在这里不明白吗?

if __name__ == '__main__': 

    HOST = 'smtp.gmail.com' 
    PORT = 465 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect((HOST, PORT)) 

    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 
    context.verify_mode = ssl.CERT_REQUIRED 
    context.load_verify_locations('mail.google.com.crt') 

    # check SNI extension 
    if ssl.HAS_SNI: 
     secure_sock = context.wrap_socket(sock, server_hostname=HOST) 
    else: 
     secure_sock = context.wrap_socket(sock) 

    cert = secure_sock.getpeercert() 
    print cert 

    if not cert or ('commonName', 'smtp.google.com') not in cert['subject'][4]: raise Exception("erroe") 

    secure_sock.recv(1024) 

    secure_sock.close() 
    sock.close() 

context.load_verify_locations('mail.google.com.crt') 

验证营业地点预计将包含可信CA证书。您指定的服务器证书不是CA证书。来自documentation

Load a set of “certification authority” (CA) certificates used to validate other peers’ certificates ...

+0

我明白了,谢谢。因此,似乎我应该始终导出第一个(从上到下)证书,因为只有这个证书是可信的? – yak

+0

这是否也意味着如果我想构建自己的CA,这不起作用?那么自签名证书呢? – yak

+0

@yak:如果您要构建自己的CA,则只需添加您自己的根CA.并且只要这些也是一个CA(通常是但不总是),自签名就可以工作。而*“因为只有这一个是可信的?”*:除非你声明它是可信的,否则任何东西都不可信。 –