HTTPS соединение с использованием сертификата PEM - PullRequest
8 голосов
/ 05 мая 2011

Я пытаюсь POST HTTPS-запросы, используя сертификат PEM, как показано ниже:

import httplib  
CERT_FILE = '/path/certif.pem'
conn = httplib.HTTPSConnection('10.10.10.10','443', cert_file =CERT_FILE)   
conn.request("POST", "/") 
response = conn.getresponse()       
print response.status, response.reason
conn.close()

У меня появляется следующая ошибка:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
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 739, in send
self.connect()
File "/usr/lib/python2.6/httplib.py", line 1116, in connect
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)
File "/usr/lib/python2.6/ssl.py", line 338, in wrap_socket
suppress_ragged_eofs=suppress_ragged_eofs)
File "/usr/lib/python2.6/ssl.py", line 118, in __init__
cert_reqs, ssl_version, ca_certs)
ssl.SSLError: [Errno 336265225] _ssl.c:339: error:140B0009:SSL       
routines:**SSL_CTX_use_PrivateKey_file**:PEM lib

Когда я удаляю cert_file из httplib,У меня следующий ответ:

200 ok

Когда я добавляю заголовок Аутентификация (как рекомендовано MattH) с пустой полезной нагрузкой поста, он также работает.

Однако, когда я ставлю товарзапрос с Путь, Тело и Заголовок, как показано ниже (я упростил их ...)

body = '<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">blablabla</S:Envelope>'
URLprov = "/syncaxis2/services/XXXsyncService"
auth_header = 'Basic %s' %  (":".join(["xxx","xxxxx"]).encode('Base64').strip('\r\n'))
conn.request("POST",URLprov,body,{'Authenticate':auth_header})

У меня 401 Несанкционированный ответ!

Как вы можете видеть, во-первых, яменя попросили предоставить PrivateKey!зачем мне PrivateKey, если я клиент?затем, когда я удаляю PrivateKey и сертификат и помещаю путь / тело / заголовки, у меня 401 Несанкционированная ошибка с сообщением WWW-Authenticate: Basic realm = "SYNCNB Server Realm".

Может ли кто-нибудь объяснитьЭта проблема?Есть ли другой способ отправить HTTPS-запрос с использованием сертификата в Python?

Ответы [ 3 ]

8 голосов
/ 05 мая 2011

Похоже, вам нужно что-то похожее на ответ, который я предоставил ранее для выполнения простой проверки подлинности сертификата клиента . Вот код для удобства, слегка измененный для вашего вопроса:

import httplib
import urllib2

PEM_FILE = '/path/certif.pem' # Renamed from PEM_FILE to avoid confusion
CLIENT_CERT_FILE = '/path/clientcert.p12' # This is your client cert!

# 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(PEM_FILE, CLIENT_CERT_FILE)
opener = urllib2.build_opener(cert_handler)
urllib2.install_opener(opener)

f = urllib2.urlopen("https://10.10.10.10")
print f.code
2 голосов
/ 05 мая 2011

См. http://docs.python.org/library/httplib.html

httplib.HTTPSConnection не проверяет сертификат сервера.

Возможность включить ваш личный сертификат, когда сервер выполняет аутентификацию клиентов на основе сертификатов. То есть сервер проверяет, что у клиента есть сертификат, подписанный ЦС, которому он доверяет, и которому разрешен доступ к его ресурсам.


Если вы не укажете необязательный аргумент cert, вы сможете подключиться к HTTPS-серверу, но не сможете проверить сертификат сервера.


Обновление

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

import httplib  
conn = httplib.HTTPSConnection('10.10.10.10','443')   
auth_header = 'Basic %s' % (":".join(["myusername","mypassword"]).encode('Base64').strip('\r\n'))
conn.request("POST", "/","",{'Authorization':auth_header}) 
response = conn.getresponse()       
print response.status, response.reason
conn.close()
1 голос
/ 05 мая 2011

Вы пытаетесь подключиться к веб-службе, которая требует аутентификации на основе сертификата клиента.

Вы уверены , что у вас есть файл PEM, а не PKCS # 12файл?Файл PEM выглядит следующим образом (да, я знаю, что включил закрытый ключ ... это просто фиктивная копия, которую я сгенерировал для этого примера):

-----BEGIN RSA PRIVATE KEY-----                                                                     
MIICXQIBAAKBgQDDOKpQZexZtGMqb7F1OMwdcFpcQ/pqtCoOVCGIAUxT3uP0hOw8                                    
CZNjLT2LoG4Tdl7Cl6t66SNzMVyUeFUrk5rkfnCJ+W9RIPkht3mv5A8yespeH27x                                    
FjGVbyQ/3DvDOp9Hc2AOPbYDUMRmVa1amawxwqAFPBp9UZ3/vfU8nxwExwIDAQAB                                    
AoGBAMCvt3svfr9zysViBTf8XYtZD/ctqYeUWEZYR9hj36CQyVLZuAnyMaWcS7j7                                    
GmrfVNygs0LXxoO2Xvi0ZOxj/mZ6EcZd8n37LxTo0GcWvAE4JjPr7I4MR2OvGYa/                                    
1696e82xwEnUdpyBv9z3ebleowQ1UWP88iq40oZYukUeignRAkEA9c7MABi5OJUq                                    
hf9gwm/IBie63wHQbB2wVgB3UuCYEa4Zd5zcvJIKz7NfhsZKKcZJ6CBVxwUd84aQ                                    
Aue2DRwYQwJBAMtQ5yBA8howP2FDqcl9sovYR0jw7Etb9mwsRNzJwQRYYnqCC5yS                                    
nOaNn8uHKzBcjvkNiSOEZFGKhKtSrlc9qy0CQQDfNMzMHac7uUAm85JynTyeUj9/                                    
t88CDieMwNmZuXZ9P4HCuv86gMcueex5nt/DdVqxXYNmuL/M3lkxOiV3XBavAkAA                                    
xow7KURDKU/0lQd+x0X5FpgfBRxBpVYpT3nrxbFAzP2DLh/RNxX2IzAq3JcjlhbN                                    
iGmvgv/G99pNtQEJQCj5AkAJcOvGM8+Qhg2xM0yXK0M79gxgPh2KEjppwhUmKEv9                                    
o9agBLWNU3EH9a6oOfsZZcapvUbWIw+OCx5MlxSFDamg                                                        
-----END RSA PRIVATE KEY-----                                                                    
-----BEGIN CERTIFICATE-----                                                                         
MIIDfjCCAuegAwIBAgIJAOYJ/e6lsjrUMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD                                    
VQQGEwJVUzELMAkGA1UECBMCRkwxDjAMBgNVBAcTBVRhbXBhMRQwEgYDVQQKEwtG                                    
b29iYXIgSW5jLjEQMA4GA1UECxMHTnV0IEh1dDEXMBUGA1UEAxMOd3d3LmZvb2Jh                                    
ci5jb20xGjAYBgkqhkiG9w0BCQEWC2Zvb0BiYXIuY29tMB4XDTExMDUwNTE0MDk0                                    
N1oXDTEyMDUwNDE0MDk0N1owgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJGTDEO                                    
MAwGA1UEBxMFVGFtcGExFDASBgNVBAoTC0Zvb2JhciBJbmMuMRAwDgYDVQQLEwdO                                    
dXQgSHV0MRcwFQYDVQQDEw53d3cuZm9vYmFyLmNvbTEaMBgGCSqGSIb3DQEJARYL                                    
Zm9vQGJhci5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMM4qlBl7Fm0                                    
YypvsXU4zB1wWlxD+mq0Kg5UIYgBTFPe4/SE7DwJk2MtPYugbhN2XsKXq3rpI3Mx                                    
XJR4VSuTmuR+cIn5b1Eg+SG3ea/kDzJ6yl4fbvEWMZVvJD/cO8M6n0dzYA49tgNQ                                    
xGZVrVqZrDHCoAU8Gn1Rnf+99TyfHATHAgMBAAGjge8wgewwHQYDVR0OBBYEFHZ+                                    
CPLqn8jlT9Fmq7wy/kDSN8STMIG8BgNVHSMEgbQwgbGAFHZ+CPLqn8jlT9Fmq7wy                                    
/kDSN8SToYGNpIGKMIGHMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxDjAMBgNV                                    
BAcTBVRhbXBhMRQwEgYDVQQKEwtGb29iYXIgSW5jLjEQMA4GA1UECxMHTnV0IEh1                                    
dDEXMBUGA1UEAxMOd3d3LmZvb2Jhci5jb20xGjAYBgkqhkiG9w0BCQEWC2Zvb0Bi                                    
YXIuY29tggkA5gn97qWyOtQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB                                    
gQAv13ewjgrIsm3Yo8tyqTUHCr/lLekWcucClaDgcHlCAH+WU8+fGY8cyLrFFRdk                                    
4U5sD+P313Adg4VDyoocTO6enA9Vf1Ar5XMZ3l6k5yARjZNIbGO50IZfC/iblIZD                                    
UpR2T7J/ggfq830ACfpOQF/+7K+LgFLekJ5dIRuD1KKyFg==                                                    
-----END CERTIFICATE-----

Читать этот вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...