Evitar la suplantación de identidad del servidor remoto con PHP y cURL

3

Estoy escribiendo un script PHP que solicita datos confidenciales de un servidor remoto. Estoy usando cURL para obtener la información del certificado del servidor remoto (para su salida, consulte a continuación).

¿Qué claves de matriz necesito para verificar la validez del certificado para asegurarme de que nadie pueda falsificarlas?

Por ejemplo, la clave [certinfo] [0] [Subject] [CN] se puede falsificar mediante un certificado autofirmado.

Simplemente podría validar el hash MD5 del archivo de paquete de CA que estoy usando en el lado del cliente, pero cuando el certificado del servidor está a punto de caducar, debo reemplazar el archivo de paquete de CA en consecuencia, y actualizar el hash en PHP. Eso es inaceptable para mí. El único consentimiento es reemplazar el archivo de paquete de CA sin actualizar el script PHP. Para eso necesito validar los atributos del certificado del servidor, que siguen siendo los mismos en la futura regeneración de certificados y no pueden ser falsificados por malhechores.

print_r (curl_getinfo ($ ch)):

[url] => https://remoteserver.com
[content_type] => text/html
[http_code] => 200
[header_size] => 148
[request_size] => 79
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.374
[namelookup_time] => 0
[connect_time] => 0.062
[pretransfer_time] => 0.203
[size_upload] => 0
[size_download] => 20618
[speed_download] => 55128
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => 0
[starttransfer_time] => 0.281
[redirect_time] => 0
[certinfo] => Array
    (
        [0] => Array
            (
                [Subject] => Array
                    (
                        [OU] => Globe Standard SSL
                        [CN] => www.remoteserver.com
                    )

                [Issuer] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2011-09-30 00:00:00 GMT
                [Expire date] => 2014-09-30 23:59:59 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => d7:c0:0b:3f:f3:3e:d6:ed:92:56:22:12:64:c1:c4:00:d7:c9:a1:1e:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Subject Key Identifier] => 13:1B:B2:52:14:3C:70:1C:B2:93:F1:C5:04:06:86:60:8A:D4:E5:5C
                [X509v3 Key Usage] => DigitalSignature,KeyEncipherment
                [X509v3 Basic Constraints] => CA:FALSE
                [X509v3 Extended Key Usage] => TLSWebServerAuthentication,TLSWebClientAuthentication
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27, CPS:http://www.globessl.com/docs/GlobeSSL_CPS.pdf
                [X509v3 CRL Distribution Points] => URI:http://crl.globessl.com/GlobeSSLDVCertificationAuthority.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.globessl.com/GlobeSSLDVCertificationAuthority.crt, OCSP-URI:http://ocsp.globessl.com
                [X509v3 Subject Alternative Name] => DNS:www.remoteserver.com,DNS:remoteserver.com
                [Signature] => 61:38:06:d4:30:9c:14:a4:e5:1e:b2:c8:c4:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

        [1] => Array
            (
                [Subject] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Issuer] => Array
                    (
                        [C] => SE
                        [O] => AddTrust AB
                        [OU] => AddTrust External TTP Network
                        [CN] => AddTrust External CA Root
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2010-06-22 00:00:00 GMT
                [Expire date] => 2020-05-30 10:48:38 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => a0:47:04:ce:a8:33:ab:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
                [X509v3 Subject Key Identifier] => C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Key Usage] => CertificateSign,CRLSign
                [X509v3 Basic Constraints] => CA:TRUE,pathlen:0
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27
                [X509v3 CRL Distribution Points] => URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c, CAIssuers-URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt, OCSP-URI:http://ocsp.usertrust.com
                [Signature] => 66:9c:13:6d:d2:7e:2c:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

    )
    
pregunta Alexander Malygin 27.10.2012 - 22:43
fuente

1 respuesta

5

La teoría es: cURL debería validar el certificado del servidor (y dice que lo hace ). La validación es un proceso complejo (consulte la sección 6 de RFC 5280 si no valora mucho su nivel de cordura), pero en general. es que, dadas algunas claves confiables a priori (que es el "conjunto de certificados CA" de cURL), puede verificar que el certificado enviado por el servidor haya sido emitido más o menos directamente por uno de estos CA confiables ( llamados "anclas de confianza" o "CA raíz" en el lenguaje X.509).

Luego, cURL también debe verificar que el nombre en el certificado del servidor realmente coincida con el nombre del servidor deseado. Esto se describe en RFC 2818 . La documentación de cURL no es clara sobre ese tema, pero las herramientas de línea de comandos de cURL que tengo aquí (7.21.4, como se distribuye con MacOS X 10.7 y 7.23.1) parecen realizar esa verificación también: tengo un servidor SSL en una máquina que tiene varios nombres DNS; Si uso un nombre incorrecto, que no coincida con lo que contiene el certificado del servidor, entonces curl se queja en voz alta:

  

curl: (35) error: 14077458: Rutinas SSL: SSL23_GET_SERVER_HELLO: razón (1112)

Por lo tanto, lo que debe hacer es usar un archivo "CA cert bundle" en el cliente que esté limitado a la menor cantidad posible de CA (posiblemente solo una). Por definición, el cliente confiará en todos a estas CA, por lo que esta es razón suficiente para limitar su número. Cuando el certificado del servidor caduca, no necesita cambiar el paquete de CA : solo necesita cambiarlo cuando uno de los CA caduque (pero el CA raíz suele tener una larga vida útil, precisamente porque se cambia uno Una de ellas implica actualizar los "paquetes de CA" o un concepto equivalente en cada cliente, lo que es tedioso y costoso).

No tiene que realizar comprobaciones adicionales desde su secuencia de comandos PHP, ya que eso sería redundante con lo que cURL ya hace.

Tenga en cuenta que recientemente ha se ha informado que una gran cantidad de aplicaciones que hacen algunos SSL arruinan totalmente la parte de validación del certificado del servidor, debido a una mala lectura de la documentación de las bibliotecas utilizadas, o la falta absoluta de dicha documentación. Al menos, cURL tiene un poco de documentación que es razonablemente clara. Le recomiendo que revise la parte de "verificación de nombre del servidor" como describí anteriormente.

    
respondido por el Thomas Pornin 27.10.2012 - 23:16
fuente

Lea otras preguntas en las etiquetas