2014-11-10 20 views
23

Sto provando a stabilire una connessione socket sicura in Python e sto avendo difficoltà con il bit SSL di esso. Ho trovato alcuni esempi di codice su come stabilire una connessione con SSL, ma coinvolgono tutti i file chiave. Il server con cui sto cercando di connettersi non ha bisogno di ricevere chiavi o certificati. La mia domanda è come faccio essenzialmente a racchiudere una connessione socket Python con SSL. So per certo che il codice da utilizzare è ADH-AES256-SHA e il protocollo è TLSv1. Questo è quello che ho cercato:Apertura di una connessione socket SSL in Python

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

Quando ho eseguito questo codice, non ottengo errori, ma ottengo una risposta vuota. Quando si tenta di eseguire il debug di questo codice nella riga di comando, digitando python nel terminale e incollando il codice riga per riga, ottengo quello che sto assumendo è un codice di stato quando si esegue sock.send(packet). La risposta intera che ottengo è 26. Se qualcuno sa cosa significa, o può aiutare in ogni caso sarebbe molto apprezzato. Grazie in anticipo!

risposta

56

Ok, ho capito cosa c'era che non andava. Era una specie di sciocco da parte mia. Ho avuto problemi two con il mio codice. Il mio primo errore è stato quando ho specificato lo ssl_version che ho inserito in TLSv1 quando avrebbe dovuto essere ssl.PROTOCOL_TLSv1. Il secondo errore è stato che non stavo referenziando il socket incapsulato, invece stavo chiamando il socket originale che ho creato. Il codice seguente sembrava funzionare per 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() 

Spero che questo possa aiutare qualcuno!

+2

Ho ricevuto questo errore: 'ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure qualche idea? – Kostanos

+0

Difficile da distinguere solo dall'output. Hai utilizzato lo snippet di codice sopra? In caso contrario, aprirò una nuova domanda e pubblicherò il codice che stai utilizzando :) – Raffi

+1

[SSL: WRONG_VERSION_NUMBER] numero di versione errato (_ssl.c: 590). Su GNU/Linux (Ubuntu 16.04) –

0

Ci si diverte molto a risolvere questi problemi, ma per me ho scoperto che l'infrastruttura sottostante per python ssl è openssl. Prova a convalidare i tuoi certificati con openssl e fallo prima di provare a far sì che python usi lo stesso stack.

Avevo bisogno di importare un certificato di root in openssl prima che potessi convalidare il certificato foglia.

Questo è stato utile.
http://gagravarr.org/writing/openssl-certs/others.shtml#ca-openssl

Un'altra cosa interessante era che due diverse build della stessa versione di Python su host diversi avevano metodi diversi. Uno aveva ssl.get_default_verify_paths() e l'altro no. La lezione qui è che python ssl è basato su openssl. Diverse librerie sottostanti ti danno un python diverso.

Python SSL è basato su openssl quindi risolvere prima i problemi relativi ai certificati in openssl.

2

Non si dovrebbe impostare PROTOCOL_TLSv1 (o TLSv1). Ciò limita la connessione solo a TLS v1.0. Invece si desidera PROTOCOL_TLS (o PROTOCOL_SSLv23 deprecato) che supporta tutte le versioni supportate dalla libreria.

Stai utilizzando un codice anonimo, perché per qualche motivo pensi di non aver bisogno di un certificato o di una chiave. Ciò significa che non esiste l'autenticazione del server e che sei vulnerabile a un uomo nel mezzo dell'attacco. A meno che tu non sappia davvero cosa stai facendo, ti suggerisco di non usare cifre anonime (come ADH-AES256-SHA).

+1

Pensi di poter fornire un esempio di come implementare un certificato o una chiave piuttosto che dire di non usare una cifra anonima? –