Python solicita verificación de SSL

2

Actualmente estoy jugando con el módulo de solicitudes en python, que te permite especificar un certificado SSL para usar en tu solicitud, usando el siguiente comando

url = r'https://www.google.com'
cert_path = r'C:\mystuff\google.crt'
requests.get(url, verify=cert_path)

Requests almacena sus CA confiables en un archivo PEM ubicado en python / Lib / site-packages / request / cacert.pem. Si especifica 'verify = True', buscará cacert.pem.

Estoy viendo el certificado para enlace a través de Chrome, y tiene la siguiente ruta de certificación.

GeoTrust Global CA - > Google Internet Authority G2 - > www.google.com

Lo que me parece extraño es que cuando extraigo todos los Certificados SSL relacionados con GeoTrust de la tienda cacert.pem, los coloco en su propio GeoTrust.pem, y apunto a las solicitudes de ese archivo, el reconocimiento falla. p>

Sin embargo, a través de prueba y error, si elimino el primer certificado SSL de cacerts.pem, que es "Equifax Secure CA", lo coloco en su propio archivo de certificado, y señalo que la solicitud funciona perfectamente.

En esencia, ¿por qué se deniega una solicitud de uso de un certificado de GeoTrust en una configuración de URL con un certificado de GeoTrust? ¿Y por qué funcionaría al especificar la raíz de Equifax?

También intenté copiar directamente desde google a través de Chrome el certificado raíz de GeoTrust como Base64, y lo agregué a GeoTrust.pem, pero el protocolo de enlace sigue fallando.

Soy nuevo en esto, por lo que cualquier ayuda sería muy apreciada

    
pregunta disflux 08.01.2016 - 19:39
fuente

1 respuesta

4
  

Soy nuevo en esto, por lo que cualquier ayuda sería muy apreciada

Esto es realmente un problema donde no solo los novatos se desesperaban. El problema es complejo y depende de implementaciones y errores específicos en las bibliotecas TLS involucradas. Por lo tanto, no es realmente su culpa que no funcione como se esperaba. Espero que la siguiente explicación pueda ser entendida:

En realidad, hay varias rutas de acceso de confianza a un certificado de confianza. Lo que el servidor envía como certificados es esto:

#0 CN=www.google.com SAN=DNS:www.google.com
#1 CN=Google Internet Authority G2
#2 CN=GeoTrust Global CA

El último certificado está firmado por #3 OU=Equifax Secure Certificate Authority que no está incluido en la cadena enviada por el servidor.

La biblioteca NSS utilizada en Chrome y Firefox comienza en la parte superior y comprueba cada certificado si puede encontrar una CA de confianza que haya firmado este certificado, es decir, un certificado que exista en el almacén de confianza local. Se detendrá con la validación en el certificado # 1, porque tiene un certificado local para GeoTrust Global CA que puede usarse para validar el certificado # 1. Por lo tanto, se hace con la validación e ignora el certificado nº 2.

OpenSSL hasta la versión 1.0.1 (al menos hasta 1.0.1p) funciona de manera diferente. Observará toda la cadena e intentará encontrar un ancla de confianza para el último certificado de la cadena. Como a menudo los servidores envían el certificado raíz dentro de la cadena (lo cual es incorrecto) eliminará todos los certificados autofirmados de la cadena antes de que busque el ancla de confianza (ya que los certificados raíz suelen ser autofirmados).

En este caso, el certificado n. ° 2 para "GeoTrust Global CA" no es un certificado autofirmado (firmado por Equifax) y no se eliminará. Por lo tanto, intentará encontrar el emisor para este certificado # 2 "GeoTrust Global CA" en el almacén de confianza para construir la cadena de confianza. Si incluyó el certificado # 3 (Equifax) en el almacén de confianza (nombre de archivo en el parámetro verify ), entonces todo está bien y la validación se realizó correctamente. Si solo incluye la "CA global de GeoTrust" en el almacén de confianza, la validación falla porque este no es el ancla de confianza correcta para el certificado n. ° 2. OpenSSL 1.0.1 es demasiado tonto como para darse cuenta de que este sería el anclaje de confianza perfecto para el certificado n. ° 1 y, por lo tanto, la validación falla.

La situación cambió finalmente (más de 3 años después de informé sobre este tipo de error ) en OpenSSL 1.0.2. Si el primer intento de validar la cadena falla, eliminará el último certificado de la cadena (certificado # 2) y lo volverá a intentar. En este caso tendrá éxito. Eso significa que si usarías una versión de Python construida con OpenSSL 1.0.2, entonces debería estar bien. Para obtener más detalles sobre las diferentes formas de validar la ruta de confianza, consulte el último comentario en OpenSSL bug # 3621 .

    
respondido por el Steffen Ullrich 08.01.2016 - 22:50
fuente

Lea otras preguntas en las etiquetas