简体   繁体   中英

Python tcp socket with ssl encryption [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

I am working on a Windows 10 computer and a Windows 10 virtual machine. I´ve created a tcp socket server/client application which is secured via python ssl. My code looks like this:

Server:

context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.set_ciphers('ECDHE-ECDSA-AES256-GCM-SHA384') 
context.load_cert_chain(certfile="cert.pem", keyfile="prKey.pem")

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((ip, port))
    
ssocket = context.wrap_socket(tcpsock, server_side=True)

Client:

context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations("cert.pem")

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock = context.wrap_socket(sock, server_hostname=server_ip)

My friend created an official certificate to use for my server-side authentication. This was created and validated via OpenSSL if I understand correctly. However, when I try to connect to the running server with my client I receive the following error message (client-side error):

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

I put the certificate + matching private key (pem format) on the virtual machine and I have a copy of the certificate (pem format) on my localhost.

I also have a certificate in cer file format, which I installed to the root windows certificate store (client and server side).

Since this did not work I kept researching and found out about the certifi package. I installed it and found by using print(certifi.where()) a cacert.pem file. Which contained multiple certificates. I added my friends certificate to that file via copy and paste, safe it but I still receive the same error.

Now I´m seriously kinda lost about what is wrong. When I disable context.verify_mode = ssl.CERT_REQUIRED my code is working just fine, but I really want server-side authentication for my code..

I changed the client's code to:

context = ssl.create_default_context()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssock = context.wrap_socket(sock, server_hostname=self.ip)

This way I don't have to hand a certificate file manually over. Instead, it seems like my Windows root certificate library gets scanned and finds my VM´s certificate automatically (since I installed the.cer file).


On the server side, I simply had to pass the certificate.cer file instead of the pem format.
 context.load_cert_chain(certfile="cert.cer", keyfile="prKey.pem")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM