开发者

HTTPS connection using PEM Certificate

I'm trying to POST HTTPS requests using a PEM certificate like following:

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()

I have the following error:

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

When I remove the cert_file from httplib, I've the following response:

200 ok

When I add the Authentication header (like advised by MattH) w开发者_如何学Pythonith empty post payload, it works also.

However, when I put the good request with the Path, the Body and the Header, like following (I simplified them...)

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})

I have 401 Unauthorized response !

As you can see, first, I'm asked to provide the PrivateKey ! why did I need the PrivateKey if I'm a client ? then, when I remove the PrivateKey and the certificate, and put the Path/Body/headers I have 401 Unauthorized error with the message WWW-Authenticate: Basic realm="SYNCNB Server Realm".

Could any one explain this issue? Is there another way to send HTTPS request using a certificate in Python?


It sounds like you need something similar to an answer I have provided before to perform simple client certificate authentication. Here is the code for convenience modified slightly for your question:

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


See http://docs.python.org/library/httplib.html

httplib.HTTPSConnection does not do any verification of the server’s certificate.

The option to include your private certificate is when the server is doing certificate based authentication of clients. I.e. the server is checking the client has a certificate signed by a CA that it trusts and is allowed to access it's resources.


If you don't specify the cert optional argument, you should be able to connect to the HTTPS server, but not validate the server certificate.


Update

Following your comment that you've tried basic auth, it looks like the server still wants you to authenticate using basic auth. Either your credentials are invalid (have you independently verified them?) or your Authenticate header isn't formatted correctly. Modifying your example code to include a basic auth header and an empty post payload:

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()


What you're doing is trying to connect to a Web service that requires authentication based on client certificate.

Are you sure you have a PEM file and not a PKCS#12 file? A PEM file looks like this (yes, I know I included a private key...this is just a dummy that I generated for this example):

-----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-----

Read this question.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜