web-dev-qa-db-fra.com

CertificateError: le nom d'hôte ne correspond pas

J'utilise un proxy (derrière le pare-feu d'entreprise) pour me connecter à un domaine https. La prise de contact SSL ne semble pas bien se passer:

CertificateError: hostname 'ats.finra.org:443' doesn't match 'ats.finra.org' 

J'utilise Python 2.7.9 - Mécanisez et j'ai dépassé tous les écrans de connexion, de mot de passe et de recherche de sécurité, mais cela se bloque sur la certification.

Toute aide serait incroyable. J'ai essayé le monkeywrench trouvé ici: Forcer Mechanize à utiliser SSLv

Ne fonctionne pas pour mon code cependant.

Si vous voulez le fichier de code, je serais heureux de l'envoyer.

14
pugmastaflex

Vous pouvez éviter cette erreur en réparant ssl par monkey:

import ssl
ssl.match_hostname = lambda cert, hostname: True
20
hoju

Ce bogue dans ssl.math_hostname apparaît dans la v2.7.9 (ce n'est pas dans 2.7.5), et a à voir avec ne pas supprimer le nom d'hôte de la syntaxe hostname: port. La réécriture suivante de ssl.match_hostname corrige le bogue. Mettez ceci avant votre code de mécanisation:

import functools, re, urlparse
import ssl

old_match_hostname = ssl.match_hostname

@functools.wraps(old_match_hostname)
def match_hostname_bugfix_ssl_py_2_7_9(cert, hostname):
    m = re.search(r':\d+$',hostname)  # hostname:port
    if m is not None:
        o = urlparse.urlparse('https://' + hostname)
        hostname = o.hostname
    old_match_hostname(cert, hostname)

ssl.match_hostname = match_hostname_bugfix_ssl_py_2_7_9

Le code de mécanisation suivant devrait maintenant fonctionner:

import mechanize
import cookielib

br = mechanize.Browser()

# Cookie Jar
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)

# Browser options
br.set_handle_equiv(True)
br.set_handle_gzip(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)

# Follows refresh 0 but not hang on refresh > 0
br.set_handle_refresh(mechanize._http.HTTPRefreshProcessor(), max_time=1)

br.addheaders = [('User-Agent', 'Nutscrape 1.0')]
# Use this proxy
br.set_proxies({"http": "localhost:3128", "https": "localhost:3128"})
r = br.open('https://www.duckduckgo.com:443/')
html = br.response().read()
# Examine the html response from a browser
f = open('foo.html','w')
f.write(html)
f.close()
4
stvs

Dans mon cas, le nom DNS du certificat était ::1 (À des fins de test local) et la vérification du nom d'hôte a échoué avec

ssl.CertificateError: hostname '::1' doesn't match '::1'

Pour le corriger un peu correctement, j'ai singé patché ssl.match_hostname Avec

import ssl                                                                                                                                                                                             
ssl.match_hostname = lambda cert, hostname: hostname == cert['subjectAltName'][0][1]

Qui vérifie réellement si les noms d'hôte correspondent.

4
fabiomaia