tlsv1 tls sslexception received net handshake_failure fatal failure debug caused java ssl groovy

tls - ssl debug java



Error al abrir la URL https: el bit keyCertSign no está configurado (1)

Supongo que estás hablando de este certificado de UTN-USERFirst-Hardware:

-----BEGIN CERTIFICATE----- MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn 0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t 3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE-----

En una versión legible para los humanos:

Version: 3 (0x2) Serial Number: 44:be:0c:8b:50:00:24:b4:11:d3:36:2a:fe:65:0a:fd Signature Algorithm: sha1WithRSAEncryption Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware Validity Not Before: Jul 9 18:10:42 1999 GMT Not After : Jul 9 18:19:22 2019 GMT Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware Subject Public Key Info: [...] X509v3 extensions: X509v3 Key Usage: Digital Signature, Non Repudiation, Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45 X509v3 CRL Distribution Points: Full Name: URI:http://crl.usertrust.com/UTN-USERFirst-Hardware.crl X509v3 Extended Key Usage: TLS Web Server Authentication, IPSec End System, IPSec Tunnel, IPSec User

Básicamente, tenemos aquí un certificado de CA con X509v3 Key Usage X509v3 Extended Key Usage y X509v3 Key Usage X509v3 Extended Key Usage .

Sin embargo, RFC 3280 dice lo siguiente sobre la extensión de uso de la clave extendida :

En general, esta extensión aparecerá solo en certificados de entidad final.

Esto no comienza demasiado bien para un certificado de CA, pero más adelante, la misma sección también dice esto:

Si un certificado contiene tanto una extensión de uso de clave como una extensión de uso de clave extendida, ambas extensiones DEBEN procesarse de manera independiente y el certificado DEBE utilizarse únicamente para un propósito consistente con ambas extensiones. Si no hay un propósito consistente con ambas extensiones, entonces el certificado NO DEBE ser utilizado para ningún propósito.

La única extensión extendida de uso de clave en este certificado que está en este RFC es la Autenticación del servidor web TLS :

id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } -- TLS WWW server authentication -- Key usage bits that may be consistent: digitalSignature, -- keyEncipherment or keyAgreement

Por supuesto, esto no es consistente con keyCertSign , que, de acuerdo con RFC 3280 (y RFC 5280). (También dudo que cualquiera de las extensiones IPSec sea compatible con keyCertSign ). Esto hace que este certificado sea inútil para emitir certificados (no es muy útil para un certificado de CA).

Me pondría en contacto con el sitio web usando este certificado para pedirles que se contacten con su CA (UTN-USERFirst-Hardware, aparentemente Comodo) y les pido que solucionen esto. Debo decir que no se ve bien proveniente de personas que hacen su dinero en la parte posterior de estos RFC.

Por supuesto, esto podría tomar un tiempo y no resolvería su problema inmediato.

Creo que he visto este DN de asunto (UTN-USERFirst-Hardware) en otros certificados de CA intermedios, por lo que el de arriba podría no ser el que estás usando.

Lo que podría hacer (siempre que pueda verificar manualmente el certificado del servidor a pesar de estos problemas) es usar un SSLContext y un TrustManager específicamente limitado para usar ese mismo certificado, para esta conexión. Esto podría evitar que el algoritmo de ruta de certificación intente encontrar el certificado de emisor y caiga en este problema.

EDITAR:

Aquí hay más detalles sobre esta solución alternativa (que aún debe mantener su conexión segura).

  • Conéctate con Firefox a este sitio web.
  • Haga clic en la barra azul / verde y elija ''Más información ...''
  • Seguridad -> Ver certificado -> Detalles
  • Elija el certificado del servidor de la lista en la parte superior y elija ''Exportar ...''
  • Lo mismo el archivo PEM en alguna parte.

Use keytool para crear un nuevo almacén de claves (elija confiar en ese certificado y elija una contraseña sensible):

keytool -importcert -keystore example.jks -file example.pem

Luego, use este código Java, que no debería ser demasiado difícil de portar a Groovy:

TrustManagerFactory tmf = TrustManagerFactory .getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream fis = new FileInputStream("/.../example.jks"); ks.load(fis, null); // or ks.load(fis, "thepassword".toCharArray()); fis.close(); tmf.init(ks); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); URL url = new URL("https://somewebsite.com"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(sslContext.getSocketFactory()); InputStream is = conn.getInputStream();

Estoy llamando a una URL https remota con el siguiente código:

def inputStream = new URL("https://somewebsite.com").openStream()

Esto funciona muy bien en mi máquina local, pero cuando despliegue en el servidor, recibo la siguiente excepción:

java.security.cert.CertPathValidatorException: CA key usage check failed: keyCertSign bit is not set

¿Cuál es la causa de este error y qué podría explicar que funcione en una máquina y no en otra?

ACTUALIZAR

Estoy ejecutando un servidor de Ubuntu en producción y desarrollo localmente en una Mac. El sitio al que intento acceder (llamémoslo peopleware.com) tiene la siguiente información de certificado:

  1. AddTrust CA raíz externa
  2. UTN-USERFirst-Hardware
  3. peopleware.com

Intenté guardar los archivos .cer de mi navegador e instalarlos en el almacén de claves en / etc / ssl / certs / java / castore