используя pyOpenSSL для создания пользовательского открывателя urllib

Эй, у меня есть API, с которым мне нужно работать. API защищен двухсторонним SSL.

У меня есть файл pem и файл crt.

Когда я регулярно подключаюсь к серверу, используя PyOpenSSL, у меня нет проблем, вот код:

import settings from OpenSSL import SSL import socket def verify(conn, cert, errnum, depth, ok): # This obviously has to be updated print 'Got certificate: %s' % cert.get_subject() return ok def password_callback(maxlen, verify, extra): print (maxlen, verify, extra) return settings.DEPOSIT_CODE context = SSL.Context(SSL.SSLv23_METHOD) context.set_verify(SSL.VERIFY_NONE, verify) context.set_passwd_cb(password_callback) context.use_certificate_file(settings.CLIENT_CERT_FILE) context.use_privatekey_file(settings.PEM_FILE) sock = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) sock.connect(("someserver.com",443)) http_get_request = """ GET / HTTP/1.1 """ sock.write(http_get_request) print sock.recv(1000) 

Но, поскольку это HTTP API, и я хочу избавиться от протокола http, ну, я реализовал для него открыватель, код как-то изменен здесь:

 import settings import socket import urllib2 def verify(conn, cert, errnum, depth, ok): # This obviously has to be updated print 'Got certificate: %s' % cert.get_subject() return ok def password_callback(maxlen, verify, extra): print (maxlen, verify, extra) return settings.DEPOSIT_CODE class MyHTTPSConnection(httplib.HTTPSConnection): def connect(self): context = SSL.Context(SSL.SSLv23_METHOD) context.set_passwd_cb(password_callback) context.use_certificate_file(settings.CLIENT_CERT_FILE) context.set_verify(SSL.VERIFY_NONE, verify) context.use_privatekey_file(settings.PEM_FILE) self.sock = SSL.Connection(context, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) class MyHTTPSHandler(urllib2.HTTPSHandler): def https_open(self,req): return self.do_open(MyHTTPSConnection,req) opener = urllib2.build_opener(urllib2.HTTPHandler,MyCHTTPSHandler) urllib2.install_opener(opener) f = urllib2.urlopen("https://sampleapiserver.com") print f.code 

но когда я запускаю второй код, я получаю следующую ошибку:

  File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout) File "/usr/lib/python2.6/urllib2.py", line 391, in open response = self._open(req, data) File "/usr/lib/python2.6/urllib2.py", line 409, in _open '_open', req) File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain result = func(*args) File "network.py", line 37, in https_open return self.do_open(IRNICHTTPSConnection,req) File "/usr/lib/python2.6/urllib2.py", line 1142, in do_open h.request(req.get_method(), req.get_selector(), req.data, headers) File "/usr/lib/python2.6/httplib.py", line 914, in request self._send_request(method, url, body, headers) File "/usr/lib/python2.6/httplib.py", line 951, in _send_request self.endheaders() File "/usr/lib/python2.6/httplib.py", line 908, in endheaders self._send_output() File "/usr/lib/python2.6/httplib.py", line 780, in _send_output self.send(msg) File "/usr/lib/python2.6/httplib.py", line 759, in send self.sock.sendall(str) OpenSSL.SSL.Error: [('SSL routines', 'SSL_write', 'uninitialized')] 

Наконец, я делаю что-то неправильно? Если нет, пожалуйста, помогите мне понять ошибку …

Ура,

  • ssl.SSLError: проверить сертификат SSL: CERTIFICATE_VERIFY_FAILED] (_ssl.c: 749)
  • Получение сертификата проверяет ошибку с механизацией
  • Обновление openssl в python 2.7
  • Ошибка SSL InsecurePlatform при использовании пакета запросов
  • Как запустить TLS в активном соединении в python?
  • Неверная версия Python Smtp SSL для Linux
  • Twisted Python Как создать twisted.web.client.BrowserLikePolicyForHTTPS с помощью настраиваемого trustRoot?
  • Python httplib SSL23_GET_SERVER_HELLO: неизвестный протокол
  • 2 Solutions collect form web for “используя pyOpenSSL для создания пользовательского открывателя urllib”

    Я не уверен – но мне кажется, что вам не хватает вызова connect () в методе connect ():

     self.sock.connect(("someserver.com",443)) 

    Кроме того, обработка https httplib имеет классы-оболочки для SSL-сокета, поэтому, возможно, они необходимы для работы?

    Похоже, вы добавляете здесь много сложностей, которые вам действительно не нужны. Если вы просто выполняете простую аутентификацию сертификата клиента, вы, вероятно, можете уйти от следующего фрагмента ( источника ):

     import httplib import urllib2 # HTTPS Client Auth solution for urllib2, inspired by # http://bugs.python.org/issue3466 # and improved by David Norton of Three Pillar Software. In this # implementation, we use properties passed in rather than static module # fields. 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): return httplib.HTTPSConnection(host, key_file=self.key, cert_file=self.cert) cert_handler = HTTPSClientAuthHandler(settings.PEMFILE, settings.CLIENT_CERT_FILE) opener = urllib2.build_opener(cert_handler) urllib2.install_opener(opener) f = urllib2.urlopen("https://sampleapiserver.com") print f.code 

    Источник использовался в контексте предоставления аутентифицированного URL-адреса для конструктора Suds Client , поэтому я снял его и сделал его прямым открывателем.

    Python - лучший язык программирования в мире.