Abrir una conexión de socket SSL en Python
sockets (3)
Estoy tratando de establecer una conexión de socket segura en Python, y estoy teniendo problemas con el bit SSL. He encontrado algunos ejemplos de código sobre cómo establecer una conexión con SSL, pero todos incluyen archivos clave. El servidor con el que intento conectarme no necesita recibir claves ni certificados. Mi pregunta es ¿cómo puedo esencialmente envolver una conexión de socket python con SSL? Sé con certeza que el cifrado que se supone que debo usar es ADH-AES256-SHA
, y el protocolo es TLSv1
. Esto es lo que he estado intentando:
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()
Cuando ejecuto este código, no obtengo ningún error, pero obtengo una respuesta en blanco. Cuando trato de depurar este código en la línea de comando, escribiendo python
en la terminal y pegando en código línea por línea, obtengo lo que sock.send(packet)
es un código de estado cuando se ejecuta sock.send(packet)
. La respuesta entera que obtengo es 26
. Si alguien sabe lo que esto significa, o puede ayudar de todos modos, sería muy apreciado. ¡Gracias por adelantado!
Es muy divertido resolver estos problemas, pero para mí, descubrí que la infraestructura subyacente para python ssl es openssl. Intenta validar tus certificados con openssl y haz esto antes de intentar que python use esa misma pila.
Necesitaba importar un certificado raíz en openssl antes de poder validar el certificado de hoja.
Esto fue útil.
http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl
Otra cosa interesante fue que dos versiones diferentes de la misma versión de python en diferentes hosts tenían diferentes métodos. Uno tenía ssl.get_default_verify_paths()
y el otro no tenía ninguno. La lección aquí es que python ssl se basa en openssl . Diferentes bibliotecas subyacentes te dan un pitón diferente.
Python SSL se basa en openssl para resolver problemas de certificados en openssl primero.
No debe configurar PROTOCOL_TLSv1
(o TLSv1
). Esto restringe la conexión a TLS
v1.0 solamente. En su lugar, desea PROTOCOL_TLS
(o el PROTOCOL_SSLv23
desuso) que admite todas las versiones admitidas por la biblioteca.
Está utilizando un cifrado anónimo porque, por algún motivo, cree que no necesita un certificado o clave. Esto significa que no hay autenticación del servidor y que eres vulnerable a un hombre en el ataque medio. A menos que realmente sepa lo que está haciendo, le sugiero que no use cifras anónimas (como ADH-AES256-SHA
).
Ok, descubrí lo que estaba mal. Fue algo tonto de mi parte Tuve two
problemas con mi código. Mi primer error fue cuando especificaba la ssl_version
que puse en TLSv1
cuando debería haber sido ssl.PROTOCOL_TLSv1
. El segundo error fue que no estaba haciendo referencia al socket envuelto, sino que estaba llamando al socket original que he creado. El siguiente código parece funcionar para mí.
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()
Espero que esto pueda ayudar a alguien!