无法使用任何 python 请求、httplib/httplib2、urllib/urlib2 从客户端验证 ssl 证书

not able to verify ssl-certificate from client side using any of python requests, httplib/httplib2, urllib/urlib2

这个问题是重复的。但我仍然在问,因为我没有从给定的答案中找到任何解决方案。所以大家不要让它重复,而是帮我解决这个问题。

我是 运行 我的服务器,使用 bottle(粘贴)作为 https。当尝试从 java 和 postman 访问时,它验证正确并且响应即将到来。

使用的版本: python 2.7.13

requests.version '2.11.1' import cryptography cryptography.version '2.1.3' import OpenSSL OpenSSL.version '17.3.0'

但不幸的是,当尝试从 python 模块访问时 - 它会抛出问题。 ?

requests.post(url, verify=_certfile, proxies=proxies) #tried #failed to verify certificate

urllib2.urlopen(url, data=data, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
        cafile=None, capath=None, cadefault=False, context=context)  #tried #failed to verify certificate

import httplib2

http = httplib2.Http(disable_ssl_certificate_validation=True)
headers, content = http.request(url, "POST", body=data, headers=headers)#tried #failed to verify certificate

httplib.HTTPSConnection(host='10.201.41.50', port=8018, key_file=key_file, cert_file=cert_file, strict=None, context=context) #tried #failed to verify certificate

我的服务器 运行 使用使用 bottle 框架的粘贴服务器。

ssl_cxt = SSL.Context(SSL.SSLv23_METHOD)
...
...
ssl_cxt.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
paste.httpserver.serve(app, host=IP, port=PORT, server_version=" ", ssl_context=ssl_cxt)

我面临的问题(每个库不同)

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "Continuum\Anaconda2\lib\site-packages\requests\api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\sessions.py", line 596, in send
r = adapter.send(request, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: unknown error (_ssl.c:2947)

============

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "Continuum\Anaconda2\lib\site-packages\requests\api.py", line 70, in get
return request('get', url, params=params, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\sessions.py", line 596, in send
r = adapter.send(request, **kwargs)
File "Continuum\Anaconda2\lib\site-packages\requests\adapters.py", line 497, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate 
verify failed (_ssl.c:661)

  File "Continuum\Anaconda2\lib\httplib.py", line 1038, in endheaders
  self._send_output(message_body)
  File "Continuum\Anaconda2\lib\httplib.py", line 882, in _send_output
  self.send(msg)
  File "Continuum\Anaconda2\lib\httplib.py", line 844, in send
  self.connect()
  File "Continuum\Anaconda2\lib\httplib.py", line 1262, in connect
  self.sock = self._context.wrap_socket(self.sock,
  AttributeError: 'Context' object has no attribute 'wrap_socket'

我尝试使用 urllib2、套接字和 ssl 来解决。我能够访问服务器。我尝试使用 .pkcs12 但似乎 urllib2 只需要 .pem 文件。所以建议尝试创建带有 .pem 扩展名的客户端证书,特别是当您尝试从 python.

访问时
import ssl
import socket
import urllib2
import json


url = "https://localhost:port/hello/"

_certfile_pem = "ssl_client.pem"
key_file = "ssl_key.pem"
cert_file = "ssl_cert.pem"

headers = {"Content-Type":"application/json"}
data = {}

context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.verify_mode = ssl.CERT_REQUIRED
context.load_cert_chain(certfile=cert_file, keyfile=key_file)
context.load_verify_locations(_certfile_pem)
context.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))  # 
socket overwrite required.

try:
    req = urllib2.Request(url,data=json.dumps(data))
    response = urllib2.urlopen(req, context=context)
    content = response.read()
    print content
except urllib2.HTTPError as e:
    content = e.read()
    print "HTTPError : ", e