带有 ssl 的 Python 套接字以防止中间攻击

Posted

技术标签:

【中文标题】带有 ssl 的 Python 套接字以防止中间攻击【英文标题】:Python socket with ssl to prevent middle attack 【发布时间】:2021-07-22 12:02:18 【问题描述】:

我有一个使用 RSA 非对称加密和套接字的应用程序。但是在我阅读this 之后,我尝试使用 ssl 套接字。我尝试了一堆代码。这是服务器:

import socket, ssl

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock = ssl.wrap_socket(sock)

sock.bind(('some ip', 9999))
sock.listen(1)
cl, ip = sock.accept()
cl.send(b'hi client')
print(cl.recv(1024))

这里是客户端:

import socket, ssl

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sock = ssl.wrap_socket(sock)

sock.connect(('same ip as server', 9999))
sock.send(b'hi server')
print(sock.recv(1024))

但是当客户端连接时(而不是客户端未运行时),我一直在服务器端获取此信息:

Traceback (most recent call last):
  File "C:/Users/avishah/PycharmProjects/Math/SocketTest/Server.py", line 9, in <module>
    cl, ip = sock.accept()
  File "C:\Python\Python38\lib\ssl.py", line 1355, in accept
    newsock = self.context.wrap_socket(newsock,
  File "C:\Python\Python38\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Python\Python38\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Python\Python38\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1125)

这在客户端:

Traceback (most recent call last):
  File "C:/Users/avishah/PycharmProjects/Math/SocketTest/Client.py", line 8, in <module>
    sock.connect(('192.168.43.254', 9999))
  File "C:\Python\Python38\lib\ssl.py", line 1342, in connect
    self._real_connect(addr, False)
  File "C:\Python\Python38\lib\ssl.py", line 1333, in _real_connect
    self.do_handshake()
  File "C:\Python\Python38\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1125)

我还添加了密码作为wrap_socket 的一部分,但这会导致同样的事情。

我实际上想要一个带有密码的服务器和客户端的简约示例。

【问题讨论】:

【参考方案1】:

SSL/TLS 的安全性基于两个原则:a) 加密流量以防止嗅探和操纵;b) 确保与正确的对等方进行通信。后者是必不可少的,否则中间的活跃人员可以简单地冒充服务器,即通信仍将被加密,但它将在客户端和攻击者之间,而不是在客户端和目标服务器之间。

验证客户端是否与正确的服务器通信通常使用证书来完成。您的代码不使用任何证书。由于出于安全原因,默认启用的密码都需要证书,因此您最终将无法使用任何可能的密码,即

  ssl.SSLError: [SSL: NO_SHARED_CIPHER] no shared cipher (_ssl.c:1125)

我实际上想要一个服务器和客户端的简约示例

official documentation of the ssl module 包含此类示例,请参阅此处。

【讨论】:

所以我需要证书... wrap 套接字需要几种类型的证书,有 certfile(我试过这个,我将 certifii.where() 传递给这个)、ca_certs 和 cert_reqs。我需要使用哪一个,我应该通过什么?官方文档似乎没有服务器端代码,所以我认为这是一个服务器端问题(它可能仍然是)。 @AviShah:“官方文档似乎没有服务器端代码” - 它有。在我链接到的地方有三个明确描述的代码块:具有默认上下文的客户端、具有自定义上下文的客户端、服务器。

以上是关于带有 ssl 的 Python 套接字以防止中间攻击的主要内容,如果未能解决你的问题,请参考以下文章

TCP套接字流和带有Swift的SSL

SSL和SSH的区别

Express框架进阶4---安全(转)

强制 SSL 客户端套接字发送证书

ReactNative 中使用SSL Pinning防止中间人攻击

linux---集群架构初探(25)HTTPS