在Python中打开SSL套接字连接

时间:2014-11-10 19:04:39

标签: python sockets ssl

我试图在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。如果有人知道这意味着什么,或者无论如何都能提供帮助,我们将不胜感激。提前谢谢!

4 个答案:

答案 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中解决证书问题。