Opening a SSL socket connection in Python
Asked Answered
D

4

57

I'm trying to establish a secure socket connection in Python, and i'm having a hard time with the SSL bit of it. I've found some code examples of how to establish a connection with SSL, but they all involve key files. The server i'm trying to connect with doesn't need to receive any keys or certificates. My question is how do I essentially wrap a python socket connection with SSL. I know for a fact that the cipher i'm suppose to use is ADH-AES256-SHA, and the protocol is TLSv1. This is what i've been trying:

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()

When I run this code, I don't get any errors, but I get a blank response. When trying to debug this code in the command line, by typing in python in the terminal and pasting in code line by line, I get what i'm assuming is a status code when running sock.send(packet). The integer response I get is 26. If anyone knows what this means, or can help in anyway it would be greatly appreciated.

Decemvir answered 10/11, 2014 at 19:4 Comment(0)
D
101

Ok, I figured out what was wrong. It was kind of foolish of me. I had two problems with my code. My first mistake was when specifying the ssl_version I put in TLSv1 when it should have been ssl.PROTOCOL_TLSv1. The second mistake was that I wasn't referencing the wrapped socket, instead I was calling the original socket that I have created. The below code seemed to work for me.

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()

Hope this can help somebody!

Decemvir answered 10/11, 2014 at 19:40 Comment(4)
I got this error: ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure any idea?Supertonic
Hard to tell from just the output. Did you use the code snippet above? If not, i'd open a new question up and post the code that you're using :)Decemvir
[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:590). Over GNU/Linux (Ubuntu 16.04)Synergism
@Supertonic You can try using a different cipher. I.e. replace ADH-AES256-SHA with AES256-SHA. If that doesn't work, try using TLSv1.2 with AES256-SHA256. Most likely the server either doesn't support the cipher or the protocol.Algerian
S
11

You shouldn't be setting PROTOCOL_TLSv1 (or TLSv1). This restricts the connection to TLS v1.0 only. Instead you want PROTOCOL_TLS (or the deprecated PROTOCOL_SSLv23) that supports all versions supported by the library.

You're using an anonymous cipher, because for some reason you think you don't need a certificate or key. This means that there is no authentication of the server and that you're vulnerable to a man in the middle attack. Unless you really know what you're doing, I suggest you don't use anonymous ciphers (like ADH-AES256-SHA).

Some answered 11/11, 2017 at 13:11 Comment(2)
Do you think you could provide example of how to implement a certificate or key versus just saying not to use an anonymous cipher?Diverticulosis
As things go, now PROTOCOL_TLS is also deprecated, in favor of either PROTOCOL_TLS_CLIENT or PROTOCOL_TLS_SERVER. See docs.python.org/3/library/ssl.html for up-to-date information.Haya
M
10

I was looking for a good working ssl socket that starts the connection with a https package. This helped me a lot but is a little outdated, so here is the code for 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)

This is as simple as possible, for more information visit https://docs.python.org/3/library/ssl.html

Mandrel answered 3/9, 2020 at 11:5 Comment(0)
T
0

There is a lot of fun to be had solving these problems but for me, I found that the underlying infrastructure for python ssl is openssl. Try validating your certificates with openssl and do this before you try to get python to use that same stack.

I needed to import a root certificate into openssl before I could validate the leaf certificate.

This was helpful.
http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl

Another interesting thing was that two different build of the same version of python on different hosts had different methods. One had ssl.get_default_verify_paths() and the other didn't had any at all. The lesson here is that python ssl is built on openssl. Different underlying libraries give you a different python.

Python SSL is built on openssl so solve certificate issues in openssl first.

Turquoise answered 7/9, 2017 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.