简体   繁体   中英

Self signed Certificate with Python SSL socket

I use a self signed certificate that I generated with the following command:

sudo make-ssl-cert generate-default-snakeoil 

And copied it to my home directory. If I run the following with this on server side:

from socket import socket, AF_INET, SOCK_STREAM
import ssl

def main():
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.verify_mode = ssl.CERT_REQUIRED
    context.load_cert_chain('/home/hfurmans/ssl-cert-snakeoil.pem', '/home/hfurmans/ssl-cert-snakeoil.key')

    host = "myipaddress"
    port = 5432
    my_socket = socket(AF_INET, SOCK_STREAM)
    my_socket.bind((host, port))
    my_socket.listen(1)
    my_socket = context.wrap_socket(my_socket, server_side=True)
    conn, addr = my_socket.accept()
    print("Connection from: " + str(addr))
    data = conn.recv(1024).decode()
    print(data)
    print("from connected user: " + str(data))
    data = str(data).upper()
    print("sending: " + str(data))
    conn.send(data.encode())
    conn.close()

if __name__ == "__main__":
    main()

I substituded my IP address. But they are the same on server and client. Here is the client code:

import socket
import ssl

hostname = "myipaddress"
context = ssl.create_default_context()

sock = socket.create_connection((hostname, 5432))
ssock = context.wrap_socket(sock, server_hostname=hostname)
print(ssock.version())
ssock.send("test")

If I run both scripts i get the following error. This is the client error:

bash-3.2$ python3 client.py 
Traceback (most recent call last):
  File "client.py", line 8, in <module>
    ssock = context.wrap_socket(sock, server_hostname=hostname)
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 1040, in _create
    self.do_handshake()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1108)

And here is the server error:

Traceback (most recent call last):
  File "server.py", line 27, in <module>
    main()
  File "server.py", line 16, in main
    conn, addr = my_socket.accept()
  File "/usr/lib/python3.6/ssl.py", line 1125, in accept
    server_side=True)
  File "/usr/lib/python3.6/ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "/usr/lib/python3.6/ssl.py", line 817, in __init__
    self.do_handshake()
  File "/usr/lib/python3.6/ssl.py", line 1077, in do_handshake
    self._sslobj.do_handshake()
  File "/usr/lib/python3.6/ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:852)

A self-signed certificate is a trick to pretend that the CA is the certificate itself. So we have to provide beforehand the client with this certificate in order to trust it when it will be encountered.

In the client, after the creation of the SSL context, I tried something similar to

context.load_verify_locations('/home/hfurmans/ssl-cert-snakeoil.pem')

and it worked.
( https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_verify_locations )

I only had to remove context.verify_mode = ssl.CERT_REQUIRED in the server because I didn't provide my client with its own certificate, but that was not the problem reported in your question.


Of course, for all of this to work, your certificate must have the correct common-name.
If the client connects to myipaddress (as a hostname), then the common-name of the certificate must be myipaddress too.

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