在 Python 中打开 SSL 套接字连接
Posted
技术标签:
【中文标题】在 Python 中打开 SSL 套接字连接【英文标题】:Opening a SSL socket connection in Python 【发布时间】:2015-01-07 04:24:41 【问题描述】:我正在尝试在 Python 中建立一个安全的套接字连接,但我很难使用它的 SSL 位。我找到了一些如何与 SSL 建立连接的代码示例,但它们都涉及密钥文件。我尝试连接的服务器不需要接收任何密钥或证书。我的问题是我如何基本上用 SSL 包装 python 套接字连接。我知道我想使用的密码是ADH-AES256-SHA
,协议是TLSv1
。这是我一直在尝试的:
import socket
import ssl
# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
HOST, PORT = 'XX.XX.XX.XX', 4434
# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
# WRAP SOCKET ???
ssl.wrap_socket(sock, ssl_version="TLSv1", ciphers="ADH-AES256-SHA")
# CONNECT AND PRINT REPLY
sock.connect((HOST, PORT))
sock.send(packet)
print sock.recv(1280)
# CLOSE SOCKET CONNECTION
sock.close()
当我运行此代码时,我没有收到任何错误,但我得到一个空白响应。当尝试在命令行中调试此代码时,通过在终端中键入python
并逐行粘贴代码,我得到我假设运行sock.send(packet)
时的状态代码。我得到的整数响应是26
。如果有人知道这意味着什么,或者无论如何可以提供帮助,将不胜感激。提前致谢!
【问题讨论】:
【参考方案1】:我正在寻找一个可以使用 https 包启动连接的良好工作 ssl 套接字。这对我帮助很大,但有点过时,所以这里是 python3 的代码:
import socket
import ssl
package = "GET /ws/LiveWebcastUpdate/22000557 HTTP/1.1\r\nHost:
www.website_name.com\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64;
rv:80.0) Gecko/20100101 Firefox/80.0\r\nAccept: */*\r\nAccept-Language: nl,en-
US;q=0.7,en;q=0.3\r\nSec-WebSocket-Version: 13\r\nOrigin:
https://www.website_name.com\r\nSec-WebSocket-Key:
NU/EsJMICjSociJ751l0Xw==\r\nConnection: keep-alive, Upgrade\r\nPragma: no-
cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n"
hostname = 'www.website_name.com'
port = 443
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
print(ssock.version())
ssock.send(package.encode())
while True:
data = ssock.recv(2048)
if ( len(data) < 1 ) :
break
print(data)
这是尽可能简单的,更多信息请访问 https://docs.python.org/3/library/ssl.html
【讨论】:
【参考方案2】:您不应该设置PROTOCOL_TLSv1
(或TLSv1
)。这将连接限制为仅TLS
v1.0。相反,您需要支持库支持的所有版本的 PROTOCOL_TLS
(或已弃用的 PROTOCOL_SSLv23
)。
您使用的是匿名密码,因为出于某种原因您认为不需要证书或密钥。这意味着没有服务器的身份验证,并且您很容易受到中间人攻击。除非你真的知道自己在做什么,否则我建议你不要使用匿名密码(如 ADH-AES256-SHA
)。
【讨论】:
您认为您可以提供如何实现证书或密钥的示例,而不是仅仅说不使用匿名密码吗?【参考方案3】:解决这些问题很有趣,但对我来说,我发现 python ssl 的底层基础设施是 openssl。尝试使用 openssl 验证您的证书并在尝试让 python 使用相同的堆栈之前执行此操作。
在验证叶证书之前,我需要将根证书导入 openssl。
这很有帮助。http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl
另一个有趣的事情是,在不同主机上相同版本的 python 的两个不同构建有不同的方法。一个有ssl.get_default_verify_paths()
,另一个根本没有。这里的教训是 python ssl 是建立在 openssl 之上的。不同的底层库给你不同的python。
Python SSL 是基于 openssl 构建的,因此请先解决 openssl 中的证书问题。
【讨论】:
【参考方案4】:好的,我知道出了什么问题。我有点傻。我的代码有two
问题。我的第一个错误是在指定ssl_version
时我输入了TLSv1
,而它应该是ssl.PROTOCOL_TLSv1
。第二个错误是我没有引用包装的套接字,而是调用了我创建的原始套接字。下面的代码似乎对我有用。
import socket
import ssl
# SET VARIABLES
packet, reply = "<packet>SOME_DATA</packet>", ""
HOST, PORT = 'XX.XX.XX.XX', 4434
# CREATE SOCKET
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
# WRAP SOCKET
wrappedSocket = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, ciphers="ADH-AES256-SHA")
# CONNECT AND PRINT REPLY
wrappedSocket.connect((HOST, PORT))
wrappedSocket.send(packet)
print wrappedSocket.recv(1280)
# CLOSE SOCKET CONNECTION
wrappedSocket.close()
希望这可以帮助别人!
【讨论】:
我收到了这个错误:ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure
有什么想法吗?
很难从输出中分辨出来。上面的代码sn-p你用了吗?如果没有,我会提出一个新问题并发布您正在使用的代码:)
[SSL: WRONG_VERSION_NUMBER] 错误的版本号 (_ssl.c:590)。通过 GNU/Linux (Ubuntu 16.04)
@Kostanos 您可以尝试使用不同的密码。 IE。将ADH-AES256-SHA
替换为AES256-SHA
。如果这不起作用,请尝试将TLSv1.2
与AES256-SHA256
一起使用。服务器很可能不支持密码或协议。以上是关于在 Python 中打开 SSL 套接字连接的主要内容,如果未能解决你的问题,请参考以下文章