python 使用带有 urllib2 的客户端证书

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1875052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:15:37  来源:igfitidea点击:

Using client certificates with urllib2

pythonsslcertificateurllib2mutual-authentication

提问by Ned Batchelder

I need to create a secure channel between my server and a remote web service. I'll be using HTTPS with a client certificate. I'll also need to validate the certificate presented by the remote service.

我需要在我的服务器和远程 Web 服务之间创建一个安全通道。我将使用带有客户端证书的 HTTPS。我还需要验证远程服务提供的证书。

  1. How can I use my own client certificate with urllib2?

  2. What will I need to do in my code to ensure that the remote certificate is correct?

  1. 如何在 urllib2 中使用我自己的客户端证书?

  2. 我需要在我的代码中做什么来确保远程证书是正确的?

采纳答案by Hank Gay

Here's a bug in the official Python bugtrackerthat looks relevant, and has a proposed patch.

这是官方 Python 错误跟踪器中的一个错误,看起来很相关,并且有一个建议的补丁。

回答by tghw

Because alex's answer is a link, and the code on that page is poorly formatted, I'm just going to put this here for posterity:

因为亚历克斯的回答是一个链接,而且该页面上的代码格式很差,所以我只想把它放在这里供后人使用:

import urllib2, httplib

class HTTPSClientAuthHandler(urllib2.HTTPSHandler):
    def __init__(self, key, cert):
        urllib2.HTTPSHandler.__init__(self)
        self.key = key
        self.cert = cert

    def https_open(self, req):
        # Rather than pass in a reference to a connection class, we pass in
        # a reference to a function which, for all intents and purposes,
        # will behave as a constructor
        return self.do_open(self.getConnection, req)

    def getConnection(self, host, timeout=300):
        return httplib.HTTPSConnection(host, key_file=self.key, cert_file=self.cert)

opener = urllib2.build_opener(HTTPSClientAuthHandler('/path/to/file.pem', '/path/to/file.pem.') )
response = opener.open("https://example.org")
print response.read()

回答by Leynos

Per Antoine Pitrou's response to the issue linked in Hank Gay's answer, this can be simplified somewhat (as of 2011) by using the included ssllibrary:

根据 Antoine Pitrou 对 Hank Gay 回答中链接的问题的回应,可以通过使用包含的ssl库来稍微简化(截至 2011 年):

import ssl
import urllib.request

context = ssl.create_default_context()
context.load_cert_chain('/path/to/file.pem', '/path/to/file.key')
opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context))
response = opener.open('https://example.org')
print(response.read())

(Python 3 code, but the ssllibrary is also available in Python 2).

(Python 3 代码,但该ssl库在 Python 2 中也可用)。

The load_cert_chainfunction also accepts an optional password parameter, allowing the private key to be encrypted.

load_cert_chain函数还接受一个可选的密码参数,允许对私钥进行加密。