[英]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.我替换了我的 IP 地址。 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.自签名证书是一种假装 CA 是证书本身的技巧。 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在客户端中,在创建 SSL 上下文后,我尝试了类似于
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 ) ( 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.我只需要在服务器中删除
context.verify_mode = ssl.CERT_REQUIRED
因为我没有为我的客户提供自己的证书,但这不是你的问题中报告的问题。
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.如果客户端连接到
myipaddress
(作为主机名),那么证书的公用名也必须是myipaddress
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.