Вопрос по https, python, ssl-certificate – Проверка SSL-сертификатов с Python

80

Мне нужно написать скрипт, который подключается к группе сайтов в нашей корпоративной интрасети по протоколу HTTPS и проверяет, действительны ли их сертификаты SSL; что срок их действия не истек, что они выданы для правильного адреса и т. д. Мы используем наш собственный внутренний корпоративный центр сертификации для этих сайтов, поэтому у нас есть открытый ключ CA для проверки сертификатов.

Python по умолчанию просто принимает и использует SSL-сертификаты при использовании HTTPS, поэтому даже если сертификат недействителен, библиотеки Python, такие как urllib2 и Twisted, просто с радостью будут использовать этот сертификат.

Is there a good library somewhere that will let me connect to a site over HTTPS and verify its certificate in this way?

Как проверить сертификат в Python?

Error: User Rate Limit Exceeded Heikki Toivonen
Error: User Rate Limit ExceededtreqError: User Rate Limit Exceededtwisted.web.client.AgentError: User Rate Limit Exceeded Glyph
Error: User Rate Limit Exceeded Glyph
Ситуация изменилась, теперь Python по умолчанию проверяет сертификаты. Я добавил новый ответ ниже. Jan-Philip Gehrcke

Ваш Ответ

9   ответов
-1

Error: User Rate Limit ExceededcurlError: User Rate Limit Exceeded0Error: User Rate Limit Exceeded

Error: User Rate Limit Exceededstackoverflow.com/a/1921551/1228491Error: User Rate Limit Exceeded
-1

Error: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded
26

contextFactorylistenSSL.

import os
import glob
from OpenSSL.SSL import Context, TLSv1_METHOD, VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, OP_NO_SSLv2
from OpenSSL.crypto import load_certificate, FILETYPE_PEM
from twisted.python.urlpath import URLPath
from twisted.internet.ssl import ContextFactory
from twisted.internet import reactor
from twisted.web.client import getPage
certificateAuthorityMap = {}
for certFileName in glob.glob("/etc/ssl/certs/*.pem"):
    # There might be some dead symlinks in there, so let's make sure it's real.
    if os.path.exists(certFileName):
        data = open(certFileName).read()
        x509 = load_certificate(FILETYPE_PEM, data)
        digest = x509.digest('sha1')
        # Now, de-duplicate in case the same cert has multiple names.
        certificateAuthorityMap[digest] = x509
class HTTPSVerifyingContextFactory(ContextFactory):
    def __init__(self, hostname):
        self.hostname = hostname
    isClient = True
    def getContext(self):
        ctx = Context(TLSv1_METHOD)
        store = ctx.get_cert_store()
        for value in certificateAuthorityMap.values():
            store.add_cert(value)
        ctx.set_verify(VERIFY_PEER | VERIFY_FAIL_IF_NO_PEER_CERT, self.verifyHostname)
        ctx.set_options(OP_NO_SSLv2)
        return ctx
    def verifyHostname(self, connection, x509, errno, depth, preverifyOK):
        if preverifyOK:
            if self.hostname != x509.get_subject().commonName:
                return False
        return preverifyOK
def secureGet(url):
    return getPage(url, HTTPSVerifyingContextFactory(URLPath.fromString(url).netloc))
def done(result):
    print 'Done!', len(result)
secureGet("https://google.com/").addCallback(done)
reactor.run()
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededURLPath(url).netlocError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Eli Courtwright
Error: User Rate Limit ExceededisError: User Rate Limit Exceededhttps://www.google.com/Error: User Rate Limit Exceeded
18

by defaultError: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

This class now performs all the necessary certificate and hostname checks by default. To revert to the previous, unverified, behavior ssl._create_unverified_context() can be passed to the context parameter.

Error: User Rate Limit Exceeded

Changed in version 3.4.3: This class now performs all the necessary certificate and hostname checks by default. To revert to the previous, unverified, behavior ssl._create_unverified_context() can be passed to the context parameter.

Error: User Rate Limit Exceededsystem-providedError: User Rate Limit ExceededЗапросыError: User Rate Limit ExceededTrust database section of PEP 476.

Error: User Rate Limit ExceededHTTPSConnectionError: User Rate Limit ExceededSSLSocketError: User Rate Limit ExceededSSLSocketError: User Rate Limit ExceededpyopensslError: User Rate Limit Exceededhere?
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
14

import httplib
import re
import socket
import sys
import urllib2
import ssl

class InvalidCertificateException(httplib.HTTPException, urllib2.URLError):
    def __init__(self, host, cert, reason):
        httplib.HTTPException.__init__(self)
        self.host = host
        self.cert = cert
        self.reason = reason

    def __str__(self):
        return ('Host %s returned an invalid certificate (%s) %s\n' %
                (self.host, self.reason, self.cert))

class CertValidatingHTTPSConnection(httplib.HTTPConnection):
    default_port = httplib.HTTPS_PORT

    def __init__(self, host, port=None, key_file=None, cert_file=None,
                             ca_certs=None, strict=None, **kwargs):
        httplib.HTTPConnection.__init__(self, host, port, strict, **kwargs)
        self.key_file = key_file
        self.cert_file = cert_file
        self.ca_certs = ca_certs
        if self.ca_certs:
            self.cert_reqs = ssl.CERT_REQUIRED
        else:
            self.cert_reqs = ssl.CERT_NONE

    def _GetValidHostsForCert(self, cert):
        if 'subjectAltName' in cert:
            return [x[1] for x in cert['subjectAltName']
                         if x[0].lower() == 'dns']
        else:
            return [x[0][1] for x in cert['subject']
                            if x[0][0].lower() == 'commonname']

    def _ValidateCertificateHostname(self, cert, hostname):
        hosts = self._GetValidHostsForCert(cert)
        for host in hosts:
            host_re = host.replace('.', '\.').replace('*', '[^.]*')
            if re.search('^%s$' % (host_re,), hostname, re.I):
                return True
        return False

    def connect(self):
        sock = socket.create_connection((self.host, self.port))
        self.sock = ssl.wrap_socket(sock, keyfile=self.key_file,
                                          certfile=self.cert_file,
                                          cert_reqs=self.cert_reqs,
                                          ca_certs=self.ca_certs)
        if self.cert_reqs & ssl.CERT_REQUIRED:
            cert = self.sock.getpeercert()
            hostname = self.host.split(':', 0)[0]
            if not self._ValidateCertificateHostname(cert, hostname):
                raise InvalidCertificateException(hostname, cert,
                                                  'hostname mismatch')


class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
    def __init__(self, **kwargs):
        urllib2.AbstractHTTPHandler.__init__(self)
        self._connection_args = kwargs

    def https_open(self, req):
        def http_class_wrapper(host, **kwargs):
            full_kwargs = dict(self._connection_args)
            full_kwargs.update(kwargs)
            return CertValidatingHTTPSConnection(host, **full_kwargs)

        try:
            return self.do_open(http_class_wrapper, req)
        except urllib2.URLError, e:
            if type(e.reason) == ssl.SSLError and e.reason.args[0] == 1:
                raise InvalidCertificateException(req.host, '',
                                                  e.reason.args[1])
            raise

    https_request = urllib2.HTTPSHandler.do_request_

if __name__ == "__main__":
    if len(sys.argv) != 3:
        print "usage: python %s CA_CERT URL" % sys.argv[0]
        exit(2)

    handler = VerifiedHTTPSHandler(ca_certs = sys.argv[1])
    opener = urllib2.build_opener(handler)
    print opener.open(sys.argv[2]).read()
HereError: User Rate Limit Exceededbackports.ssl_match_hostname.
Error: User Rate Limit Exceededbugs.python.org/issue1589
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Eli Courtwright
Error: User Rate Limit Exceeded Eli Courtwright
29

match_hostname()ssl

pip install backports.ssl_match_hostname

setup.py

from backports.ssl_match_hostname import match_hostname, CertificateError
...
sslsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_SSLv3,
                      cert_reqs=ssl.CERT_REQUIRED, ca_certs=...)
try:
    match_hostname(sslsock.getpeercert(), hostname)
except CertificateError, ce:
    ...
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededgetpeercert()Error: User Rate Limit Exceededmatch_hostname().
Error: User Rate Limit Exceeded
8

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded если хочешь. Настольный клиент ChandlerError: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

Error: User Rate Limit ExceededError: User Rate Limit ExceededError: User Rate Limit Exceeded

13

import requests
requests.get('https://somesite.com', cert='/path/server.crt', verify=True)

Error: User Rate Limit Exceededby defaultError: User Rate Limit ExceededverifyError: User Rate Limit Exceeded
Error: User Rate Limit ExceededcertError: User Rate Limit ExceededverifyError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
25

Error: User Rate Limit ExceededError: User Rate Limit Exceeded

Error: User Rate Limit Exceededpycurl.errorError: User Rate Limit Exceeded

import pycurl

curl = pycurl.Curl()
curl.setopt(pycurl.CAINFO, "myFineCA.crt")
curl.setopt(pycurl.SSL_VERIFYPEER, 1)
curl.setopt(pycurl.SSL_VERIFYHOST, 2)
curl.setopt(pycurl.URL, "https://internal.stuff/")

curl.perform()

Error: User Rate Limit Exceeded

Error: User Rate Limit Exceeded

(60, 'Peer certificate cannot be authenticated with known CA certificates')
(51, "common name 'CN=something.else.stuff,O=Example Corp,C=SE' does not match 'internal.stuff'")

Error: User Rate Limit Exceeded

http://curl.haxx.se/libcurl/c/curl_easy_setopt.html http://curl.haxx.se/libcurl/c/curl_easy_getinfo.html

Похожие вопросы