Python3:使用客户端证书认证从HTTPS服务器获取资源
我遇到了一个问题,想从一个https服务器获取html页面。这个资源的访问是需要客户端证书验证的(在浏览器中,我必须选择合适的证书才能访问这个页面)。
我尝试使用Python的 http.client
库,代码是这样的:
import http.client
conn = http.client.HTTPSConnection('example.com', 443, key_file = 'tmp/private.pem', cert_file = 'tmp/public.pem')
conn.set_debuglevel(0)
conn.request('GET', '/index.htm')
result = conn.getresponse()
if result.status != http.client.ACCEPTED:
pass
print(result.status, result.reason)
conn.close()
但是运行这个程序后,我得到的结果是:403 Forbidden
。我哪里做错了呢?
需要注意的是,我可以通过浏览器直接访问这个资源。私钥和公钥是从一个pkcs12文件中提取出来的,这个文件是用openssl命令从浏览器导出的(命令是 openssl pkcs12 -nocerts -nodes -in cert.p12 -out private.pem
和 openssl pkcs12 -nokeys -in cert.p12 -out public.pem
)。
1 个回答
0
因为到现在为止我还没有得到任何答案,所以我想和大家分享一下我做了什么,以及我是如何解决这个问题的。
我尝试了在这个StackOverflow问题中提供的代码示例,并稍微修改了一下,使其适用于Python3:
from urllib.request import Request, urlopen, HTTPSHandler, build_opener
from urllib.error import URLError, HTTPError
import http.client
class HTTPSClientAuthHandler(HTTPSHandler):
def __init__(self, key, cert):
HTTPSHandler.__init__(self)
self.key = key
self.cert = cert
def https_open(self, req):
return self.do_open(self.getConnection, req)
def getConnection(self, host, timeout=300):
return http.client.HTTPSConnection(host, key_file=self.key, cert_file=self.cert)
opener = build_opener(HTTPSClientAuthHandler(private_key_file, public_key_file))
response = opener.open("https://example.com/index.htm")
print response.read()
现在它开始正常工作了。我仍然不知道如何解决我最初的问题,但至少我知道怎么避免它。
希望这对你们有帮助!