Urllib和服务器证书的验证

khe*_*aud 14 python ssl urllib ssl-certificate

我使用python 2.6并请求Facebook API(https).我想我的服务可能是Man In The Middle攻击的目标.我今天早上发现再次阅读urllib模块文档:引文:

Warning : When opening HTTPS URLs, it is not attempted to validate the server certificate. Use at your own risk!
Run Code Online (Sandbox Code Playgroud)

您是否有提示/ url /示例来完成完整的证书验证?

谢谢你的帮助

小智 9

您可以创建一个urllib2开启工具,可以使用自定义处理程序为您进行验证.以下代码是一个适用于Python 2.7.3的示例.它假定您已将http://curl.haxx.se/ca/cacert.pem下载到保存脚本的同一文件夹中.

#!/usr/bin/env python
import urllib2
import httplib
import ssl
import socket
import os

CERT_FILE = os.path.join(os.path.dirname(__file__), 'cacert.pem')


class ValidHTTPSConnection(httplib.HTTPConnection):
        "This class allows communication via SSL."

        default_port = httplib.HTTPS_PORT

        def __init__(self, *args, **kwargs):
            httplib.HTTPConnection.__init__(self, *args, **kwargs)

        def connect(self):
            "Connect to a host on a given (SSL) port."

            sock = socket.create_connection((self.host, self.port),
                                            self.timeout, self.source_address)
            if self._tunnel_host:
                self.sock = sock
                self._tunnel()
            self.sock = ssl.wrap_socket(sock,
                                        ca_certs=CERT_FILE,
                                        cert_reqs=ssl.CERT_REQUIRED)


class ValidHTTPSHandler(urllib2.HTTPSHandler):

    def https_open(self, req):
            return self.do_open(ValidHTTPSConnection, req)

opener = urllib2.build_opener(ValidHTTPSHandler)


def test_access(url):
    print "Acessing", url
    page = opener.open(url)
    print page.info()
    data = page.read()
    print "First 100 bytes:", data[0:100]
    print "Done accesing", url
    print ""

# This should work
test_access("https://www.google.com")

# Accessing a page with a self signed certificate should not work
# At the time of writing, the following page uses a self signed certificate
test_access("https://tidia.ita.br/")
Run Code Online (Sandbox Code Playgroud)

运行这个脚本你应该看到像这样的输出:

Acessing https://www.google.com
Date: Mon, 14 Jan 2013 14:19:03 GMT
Expires: -1
...

First 100 bytes: <!doctype html><html itemscope="itemscope" itemtype="http://schema.org/WebPage"><head><meta itemprop
Done accesing https://www.google.com

Acessing https://tidia.ita.br/
Traceback (most recent call last):
  File "https_validation.py", line 54, in <module>
    test_access("https://tidia.ita.br/")
  File "https_validation.py", line 42, in test_access
    page = opener.open(url)
  ...
  File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1177, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed>
Run Code Online (Sandbox Code Playgroud)

  • `def __init __(self,*args,**kwargs):httplib.HTTPConnection .__ init __(self,*args,**kwargs)`对我来说似乎没用 (3认同)