¿Cómo hacer que las solicitudes de Python confíen en un certificado SSL autofirmado?


82
import requests
data = {'foo':'bar'}
url = 'https://foo.com/bar'
r = requests.post(url, data=data)

Si la URL usa un certificado autofirmado, esto falla con

requests.exceptions.SSLError: [Errno 1] _ssl.c:507: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

Sé que puedo pasar Falseal verifyparámetro, así:

r = requests.post(url, data=data, verify=False)

Sin embargo, lo que me gustaría hacer es señalar las solicitudes a una copia de la clave pública en el disco y decirle que confíe en ese certificado.


Respuestas:


60

tratar:

r = requests.post(url, data=data, verify='/path/to/public_key.pem')

1
¿Puede hacer lo mismo y utilizar certificados de cliente al mismo tiempo? Tengo problemas con esto.
— user1156544

9
Tenga en cuenta que el archivo .pem que pase debe incluir el certificado del servidor y cualquier certificado intermedio . Perdí algunas horas tratando de averiguar por qué no funcionó después de agregar el certificado del servidor.
— ChrisBob

Agregué certificate.pem autofirmado y funcionó.
— HS Rathore

4
Esta técnica no funcionó para mí. Solía ssl.get_server_certificatedescargar un certificado (self-signed.badssl.com, 443), guardé ese certificado en cert.pem, y luego lo ejecuté requests.get('https://self-signed.badssl.com/', verify='cert.pem')y todavía falló con un error de SSL (ese certificado está autofirmado).
— Jason R. Coombs

41

Con el verifyparámetro puede proporcionar un paquete de autoridad certificadora personalizado

requests.get(url, verify=path_to_bundle_file)

De los documentos :

Puede pasar verifyla ruta a un archivo CA_BUNDLE con certificados de CA confiables. Esta lista de CA de confianza también se puede especificar mediante la variable de entorno REQUESTS_CA_BUNDLE.


2
Para que quede muy claro, la variante inferior con cert=(...)es SOLO para SSL de cliente , también conocido como TLS mutuo. Si bien es interesante, es mucho más raro y realmente no se trata de la pregunta.
— Nick T

@ nick-t Gracias por el comentario. Tiene razón, he eliminado la parte inferior de la respuesta para que sea menos detallada.
— Dr. Jan-Philip Gehrcke

23

Lo más fácil es exportar la variable REQUESTS_CA_BUNDLEque apunta a su autoridad de certificación privada o un paquete de certificados específico. En la línea de comando puede hacerlo de la siguiente manera:

export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem
python script.py

Si tiene su autoridad de certificación y no desea escribir el exportcada vez, puede agregar el REQUESTS_CA_BUNDLEa su de la ~/.bash_profilesiguiente manera:

echo "export REQUESTS_CA_BUNDLE=/path/to/your/certificate.pem" >> ~/.bash_profile ; source ~/.bash_profile

La variable de entorno era lo que necesitaba para que PyCharm funcionara con los certificados almacenados en el archivo cert de OpenSSL.
— Brady

Tengo un certificado autofirmado en la cadena. Esta solución resolvió mi problema con la biblioteca boto3.
— Ilkin

6

El caso en el que se necesitan varios certificados se resolvió de la siguiente manera: Concatenar los archivos pem raíz múltiples, myCert-A-Root.pem y myCert-B-Root.pem, en un archivo. Luego, configure las solicitudes REQUESTS_CA_BUNDLE var en ese archivo en mi ./.bash_profile.

$ cp myCert-A-Root.pem ca_roots.pem
$ cat myCert-B-Root.pem >> ca_roots.pem
$ echo "export REQUESTS_CA_BUNDLE=~/PATH_TO/CA_CHAIN/ca_roots.pem" >> ~/.bash_profile ; source ~/.bash_profile

Ese fue mi momento "ahhh" del día ... Muchas gracias ... Con esta pista obtuve mi certificado jira autofirmado para que funcionara ... ;-) Sé que tal vez hay cientos de sitios y respuestas que describen esto , pero encontré el tuyo, así que obtienes mi crédito por ayudarme a resolver mi problema ... d
— alexrjs

4

La configuración export SSL_CERT_FILE=/path/file.crtdebería hacer el trabajo.


Gracias. Funciona para mí (mientras que la REQUESTS_CA_BUNDLEvariable no tiene ningún efecto en mi caso).
— Pascal H.

0

En caso de que alguien aterrice aquí (como lo hice yo) y busque agregar una CA (en mi caso Charles Proxy) para httplib2, parece que puede agregarlo al cacerts.txtarchivo incluido con el paquete de python.

Por ejemplo:

cat ~/Desktop/charles-ssl-proxying-certificate.pem >> /usr/local/google-cloud-sdk/lib/third_party/httplib2/cacerts.txt

Las variables de entorno a las que se hace referencia en otras soluciones parecen ser específicas de las solicitudes y no fueron recogidas por http:


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.