2017-07-14 6 views
0

J'essaie de créer une connexion socket en utilisant python.Vérifiez Peer en python

Voici mon code python ...

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
socket.settimeout(config['timeout']) 
self.socket.connect((config['host'], config['port'])) 

self.ssl = ssl.wrap_socket(
    self.socket, 
    certfile=config['certificate'], 
    keyfile=config['key'] 
) 

Il ne fonctionne pas comme le certificat de serveur distant semble être auto-signé ou manquant du magasin de confiance. Je suis nouveau sur python et je n'arrive pas à comprendre comment désactiver verify_peer en python pour que la connexion fonctionne.

Je code de travail en php ...

$context = stream_context_create([ 
    'ssl' => [ 
     'verify_peer' => false, 
     'local_cert' => $config['certificate'], 
     'local_pk' => $config['key'] 
    ] 
]); 

$socket = stream_socket_client(
    'ssl://secure.test.com:700', 
    $errno, $errstr, $config['timeout'], 
    STREAM_CLIENT_CONNECT, $context 
); 

Réglage 'verify_peer' => false aide à établir la connexion. Comment puis-je faire quelque chose comme ça en python?

OpenSSL debug

openssl s_client -connect secure.test.com:700 

verify error:num=20:unable to get local issuer certificate 
verify return:1 

verify error:num=21:unable to verify the first certificate 
verify return:1 

S'il vous plaît aider et suggérer. Merci

+0

* "Réglage' verify_peer => false' aide à établir la Comment puis-je faire quelque chose comme ça en python? "* - Très mauvaise idée; voir [Le code le plus dangereux au monde: la validation des certificats SSL dans les logiciels sans navigateur] (http://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html). – jww

+0

* "Cela n'a pas fonctionné car le certificat du serveur distant semble être auto-signé ou manquant dans le Trust Store ..." * - Lequel est-ce? Le cas d'utilisation affecte la réponse. Veuillez publier l'URL que vous utilisez pour vous connecter au serveur et publier la sortie de 'openssl s_client -connect : -tls1 -servername | openssl x509 -text -noout'. Faites-le en l'ajoutant à votre question en cliquant sur * Modifier * (et ne le postez pas en commentaire). Sinon, nous ne pouvons pas le reproduire et il n'y a pas assez d'informations pour vous aider à le résoudre. – jww

+0

@jww Merci pour votre aide. J'ai modifié la question avec plus de détails. J'obtiens cette erreur: 'verify error: num = 20: impossible d'obtenir le certificat de l'émetteur local' a déjà essayé de ré-acquérir le certificat actuel via une commande Linux' openssl s_client -connect secure.test.com: 700: ' – seoppc

Répondre

0

Désactiver la validation de certificat peut simplement être fait en ajoutant cert_reqs = ssl.CERT_NONE. Mais, juste la validation du certificat de désactivation est une très mauvaise idée puisque vous savez ouvert à man-in-the-middle attacks.

Par conséquent, vous devez vérifier que le certificat est celui attendu. Avec les certificats auto-signés (et d'autres), vous pouvez vérifier par exemple que le certificat reçu correspond à l'empreinte digitale du certificat prévu, comme dans le code suivant:

import socket 
import ssl 
import hashlib 

dst = ('www.paypal.com',443) 
fp_expected = '0722d46c216327bab8075f5db57ebed64d80e6699204c249c3f6ea9cc281c15b' 

# connect to the target with TCP 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
s.connect(dst) 

# upgrade the socket to SSL without checking the certificate 
s = ssl.wrap_socket(s,cert_reqs = ssl.CERT_NONE) 

# get certificate, compute fingerprint and check against expected value 
cert_bin = s.getpeercert(True) 
fp = hashlib.sha256() 
fp.update(cert_bin) 
assert(fp.hexdigest() == fp_expected) 
+0

Merci pour les explications. Je suis coincé avec cette erreur.'verify error: num = 20: impossible d'obtenir le certificat de l'émetteur local' et' verify error: num = 21: impossible de vérifier le premier certificat' quand je lance 'openssl s_client -connect secure.test.com:700 -key client. key -cert client.crt' donc j'ai pensé désactiver la vérification de certificat. – seoppc

+0

@seoppc: le code ci-dessus peut être utilisé pour vérifier au moins que le certificat du serveur est celui attendu s'il est auto-signé ou en quelque sorte cassé. Mais il devrait y avoir un bon certificat + chaîne alors peut-être que vous le faites mal depuis le début: cela pourrait par exemple être que le serveur vous oblige à utiliser l'extension SNI pour obtenir le bon certificat et la chaîne qu'un wrap_socket simple n'obtiendra pas. Notez que je ne peux pas tester cela avec s_client puisque secure.test.com:700 n'est pas accessible depuis mon emplacement, c'est-à-dire que la connexion TCP échoue déjà. –