web-dev-qa-db-fra.com

Python - SSL - numéro de version incorrect

Ce ne sera probablement qu'un autre fil non résolu mais je remplirai quand même quelques informations.

Je n'arrive pas à regrouper mon SSL, même pas une seconde. Des idées sur ce que je fais mal avec mes wrap_socket () et do_handshake ()?

Les fichiers clés semblent être parfaits à 100%, et j'ai essayé avec AND sans le .recv () avant la prise de contact. Cela génère simplement ceux-ci en fonction de l'endroit où je mets le recv ():

SSL3_GET_CLIENT_HELLO: mauvais numéro de version

SSL3_GET_RECORD: mauvais numéro de version

class Server():
    def __init__(self, listen = '', port = 8080, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        newsocket, fromaddr = self.sock.accept()
        newsocket.recv(32)
        newsocket.setblocking(0)
        sslsock = ssl.wrap_socket(newsocket,
                                    server_side=True,
                                    certfile="./kernel/sock/server.crt",
                                    keyfile="./kernel/sock/server.key",
                                    cert_reqs=ssl.CERT_NONE,
                                    ssl_version=ssl.PROTOCOL_TLSv1,
                                    do_handshake_on_connect=False,
                                    suppress_ragged_eofs=True)
        sslsock.do_handshake()
        return sslsock, fromaddr

Pour mémoire, si ce n'est pas évident ou que je me trompe, c'est la poignée de main qui échoue :)

J'ai modifié un peu le code, en essayant SSLv3 et en changeant aussi un peu la position du wrapping:

import socket, ssl, time, select

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        self.sock = ssl.wrap_socket(self.sock,
                                    server_side=True,
                                    certfile="./kernel/sock/server.crt",
                                    keyfile="./kernel/sock/server.key",
                                    cert_reqs=ssl.CERT_NONE,
                                    ssl_version=ssl.PROTOCOL_SSLv3,
                                    do_handshake_on_connect=False,
                                    suppress_ragged_eofs=True)

        newsocket, fromaddr = self.sock.accept()

        print [newsocket.recv(32)]
        newsocket.setblocking(False)
        newsocket.do_handshake()

        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print ns.recv(1024)

Maintenant, je reçois avec le newsocket.recv (32):

ssl.SSLError: [Errno 1] _ssl.c: 1331: erreur: 140940E5: routines SSL: SSL3_READ_BYTES: échec de la prise de contact SSL

et sans:

ssl.SSLError: [Errno 2] _ssl.c: 490: L'opération ne s'est pas terminée (lecture)

Aussi: je refuse d'utiliser Twisted

Réduire les choses:

import socket, ssl, time, select
from OpenSSL import SSL

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file("server.pem")
        ctx.use_certificate_file("server.pem")
        self.sock = SSL.Connection(ctx, socket.socket())

        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        newsocket, fromaddr = self.sock.accept()
        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print ns.recv(1024)

Cela fonctionne aussi bien que la bibliothèque ssl "native". Cependant maintenant j'obtiens cette erreur:

OpenSSL.SSL.Error: [('Routines SSL', 'SSL23_READ', 'échec de la prise de contact SSL')]


C'est où j'en suis maintenant:

import socket, ssl, time #, select

class Server():
    def __init__(self, listen = '', port = 443, ssl = False):
        self.sock = socket.socket()
        self.sock.bind((listen, port))
        self.sock.listen(5)

    def accept(self):
        self.ssl_sock = None
        while not self.ssl_sock:
            self.ssl_sock = ssl.wrap_socket(self.sock,
                server_side=True,
                certfile=r"C:\moo.pem",
                keyfile=r"C:\moo.key",
                cert_reqs=ssl.CERT_NONE,
                ssl_version=ssl.PROTOCOL_TLSv1)

        newsocket, fromaddr = self.ssl_sock.accept()

        print([newsocket.recv()])

        return newsocket, fromaddr

s = Server()
ns, na = s.accept()
print(ns.recv(1024))

Cela fonctionne "parfaitement" dans Firefox, mais PAS dans Google Chrome. Pourquoi? quelle est la différence? -.-

14
Torxed

Je ne sais pas Python du tout pour vous dire si vous avez un problème dans votre code.
L'erreur est cependant claire. Le client prend en charge SSLv3 et votre serveur uniquement TLSv1.
Vous devez donc activer la prise en charge de SSLv3 ou mettez à niveau votre client.

Cette ligne semble être le problème: ssl_version=ssl.PROTOCOL_TLSv1. Vous pouvez également ajouter SSLv3 ici?

Mettre à jour:
Je constate que vous avez un problème entre les navigateurs. Voir si SSLv3 est activé dans Crome.
Dans IE par exemple, c'est sous Internet Options-> Advanced Tab.
Quelque chose de similaire devrait être dans Chrome. Désactiver SSv3 et activer TLSv1 au lieu

7
Cratylus