2009-12-09 21 views
16

Necesito crear un canal seguro entre mi servidor y un servicio web remoto. Usaré HTTPS con un certificado de cliente. También necesitaré validar el certificado presentado por el servicio remoto.Uso de certificados de cliente con urllib2

  1. ¿Cómo puedo usar mi propio certificado de cliente con urllib2?

  2. ¿Qué tendré que hacer en mi código para asegurar que el certificado remoto sea el correcto?

Respuesta

29

Debido a que la respuesta de Alex es un enlace, y el código de esa página no está bien formateado, sólo voy a poner esto aquí para la posteridad: la respuesta

import urllib2, httplib 

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, timeout=300): 
     return httplib.HTTPSConnection(host, key_file=self.key, cert_file=self.cert) 

opener = urllib2.build_opener(HTTPSClientAuthHandler('/path/to/file.pem', '/path/to/file.pem.')) 
response = opener.open("https://example.org") 
print response.read() 
+0

¡Muchas gracias por esto! He estado rastreando un error durante días usando un certificado privado y una autoridad de certificación para conectarme a un servidor Apache usando la biblioteca de solicitudes en Python. Pude verificar que mi certificado funcionaba en el navegador, pero falló todo el tiempo con un "error de handshake" Terminé usando la clase anterior para probar que el certificado del cliente funcionaba y autenticaba correctamente. Resultó que había un error en la versión de la biblioteca de solicitudes que estaba usando 1.2.3 para ser exactos. Esperemos que este comentario ayude a otras personas que enfrentan el mismo problema. – ihatecache

+0

Soy nuevo en Python, por lo que me gustaría saber: ¿cuándo se llama aquí a la función https_open()? Si es posible, describa cuál es el flujo de ejecución de este código. – rrsuj

+0

Así que he seguido estas instrucciones y aparece un error de actualización: "verificación de certificado ssl falló" cuando uso Python 2.7.9 o superior. Creo que necesito agregar un SSLContext con mi propia cadena de certificados, pero no estoy 100% seguro, ¿te importa dar algún consejo o sugerencias sobre cómo trabajar en tu ejemplo aquí? ¡Gracias! – macguru2000

1

por Antoine de Pitrou a la cuestión vinculada en la respuesta de Hank Gay, esto se puede simplificar un tanto (a partir de 2011) mediante el uso de la biblioteca incluida ssl:

import ssl 
import urllib.request 

context = ssl.create_default_context() 
context.load_cert_chain('/path/to/file.pem', '/path/to/file.key') 
opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context)) 
response = opener.open('https://example.org') 
print(response.read()) 

(código de Python 3, pero la biblioteca ssl también está disponible en Python 2).

La función load_cert_chain también acepta un parámetro de contraseña opcional que permite encriptar la clave privada.

Cuestiones relacionadas