我试图在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
。如果有人知道这意味着什么,或者无论如何都能提供帮助,我们将不胜感激。提前谢谢!
答案 0 :(得分:69)
好的,我弄清楚出了什么问题。这对我来说有点愚蠢。我的代码遇到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()
希望这可以帮助别人!
答案 1 :(得分:4)
您不应该设置PROTOCOL_TLSv1
(或TLSv1
)。这仅限制与TLS
v1.0的连接。相反,您希望PROTOCOL_TLS
(或已弃用的PROTOCOL_SSLv23
)支持该库支持的所有版本。
您使用的是匿名密码,因为某些原因您认为自己不需要证书或密钥。这意味着没有服务器的身份验证,并且您在中间攻击中容易受到攻击。除非你真的知道你在做什么,否则我建议你不要使用匿名密码(如ADH-AES256-SHA
)。
答案 2 :(得分:3)
我一直在寻找一个可以正常工作的ssl套接字,该套接字可以通过https程序包开始连接。这对我有很大帮助,但是有点过时了,所以这是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
亲切的问候,
冲绳(Niek Tuytel)
答案 3 :(得分:0)
解决这些问题有很多乐趣,但对我来说,我发现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中解决证书问题。