2011-03-05 9 views
10

¿La implementación de TrustManager de Java se ignora si un certificado ha caducado?
Intenté lo siguiente:
- Utilizando keytool y el parámetro -startdate "1970/01/01 00:00:00" Creé un almacén de claves P12 con un certificado caducado.
- Me exporta el certificado:Comportamiento de trustmanager de Java en certificados caducados

Keystore type: PKCS12 
Keystore provider: SunJSSE 

Your keystore contains 1 entry 

Alias name: fake 
Creation date: 5 ╠ά± 2011 
Entry type: PrivateKeyEntry 
Certificate chain length: 1 
Certificate[1]: 
Owner: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR 
Issuer: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR 
Serial number: -1c20 
Valid from: Thu Jan 01 00:00:00 EET 1970 until: Fri Jan 02 00:00:00 EET 1970 
Certificate fingerprints: 
     MD5: A9:BE:3A:3D:45:24:1B:4F:3C:9B:2E:02:E3:57:86:11 
     SHA1: 21:9D:E1:04:09:CF:10:58:73:C4:62:3C:46:4C:76:A3:81:56:88:4D 
     Signature algorithm name: SHA1withRSA 
     Version: 3 


******************************************* 

utilicé este certificado como certificado de servidor para Tomcat.
Luego, utilizando un Apache HttpClient he conectado a Tomcat, pero primero añadido el certificado caducado a la confianza-tienda del cliente (utilizando un TrustManager

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 

y cargar el certificado caducado).
Esperaba que la conexión fallara.
En cambio, la conexión tiene éxito.
Usando System.setProperty("javax.net.debug", "ssl");
veo:

*** 
Found trusted certificate: 
[ 
[ 
    Version: V3 
    Subject: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR 
    Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5 

    Key: Sun RSA public key, 1024 bits 
    modulus: 10350555024148635338735220482157687267055139906998169922552357357346372886164908067983097037540922519808845662295379579697361784480052371935565129553860304254832565723373586277732296157572040989796830623403187557540749531267846797324326299709274902019299 
    public exponent: 65537 
    Validity: [From: Thu Jan 01 00:00:00 EET 1970, 
       To: Fri Jan 02 00:00:00 EET 1970] 
    Issuer: CN=Malicious, OU=Mal, O=Mal, L=Fake, ST=GR, C=GR 
    SerialNumber: [ -1c20] 

] 

veo que en TLS apretón de manos el certificado caducado se envía por el conector Tomcat.
Pero el cliente (es decir, el TrustManager) no rechaza la conexión.
¿Es este el comportamiento predeterminado?
¿Debo configurar el administrador de confianza para verificar la caducidad?

ACTUALIZACIÓN:
He encontrado que la TrustManager real utilizado es X509TrustManagerImpl. Aquí X509TrustManagerImpl dice que esta clase tiene una lógica mínima. ¿Puedo estar utilizando el TrustManager incorrecto?

Update2: Desde el javadoc X509TrustManager no está claro si se comprueba de caducidad del certificado

void checkServerTrusted(X509Certificate[] chain,String authType) 
           throws CertificateException 

Dada la cadena certificado parcial o completa proporcionada por el pares, construir un camino certificado a una raíz de confianza y devuelva si puede ser validada y es confiable para el servidor autenticación SSL basada en el auténtico tipo de autenticación. El tipo de autenticación es la parte del algoritmo de intercambio de claves de las suites de cifrado representado como una cadena, como "RSA", "DHE_DSS". Nota: para algunas suites de cifrado exportables , el algoritmo de intercambio clave se determina en tiempo de ejecución durante el protocolo de enlace. Para ejemplo, para TLS_RSA_EXPORT_WITH_RC4_40_MD5, la authType debe ser RSA_EXPORT cuando se utiliza una clave RSA efímero para el intercambio de claves , y RSA cuando la llave de se utiliza el certificado de servidor. La comprobación distingue entre mayúsculas y minúsculas.

Gracias

+0

¿Has encontrado alguna solución, cómo forzar la caducidad del certificado de verificación de Tomact? ¿Alguna otra implementación de 'X509TrustManager' existente que lo hace? – Andremoniy

+1

@Andremoniy: debe escribir su propio administrador de confianza personalizado – Cratylus

Respuesta

1

Yo no probar el ejemplo, pero ahora tengo que suelo para regenerar mis certificados de servidor (para nuestro servidor de desarrollo) ya que sus certificados tienen validez tiempos muy cortos.

En nuestro caso, el cliente no tiene los certificados del servidor en el almacén de confianza, solo el certificado de nuestra CA (con validez más larga) y cuando el cliente intenta conectarse al servidor, ambos lados obtienen una SSLException (que puede ser envuelto en otra excepción en su caso).

Supongo que el administrador de confianza asume algo así como "si me das certificados caducados para confiar, lo haré". Pruebe nuestro enfoque en su lugar (también le permite actualizar el cliente cada vez que el certificado del servidor expira).

+1

@Paulo: 1) Almacenar el certificado de CA únicamente. Entonces, si el cliente recibe un certificado caducado (firmado por su CA), el administrador de confianza lo rechaza. 2) Lo que sugiere es justo, pero desde mi punto de vista, si este es el comportamiento predeterminado del administrador de confianza es al menos extraño. ¿Qué pasa si el certificado expiró hace 10 horas? El administrador de confianza lo aceptaría como de confianza, porque ya está en el almacén de confianza? Creo que este no es el comportamiento correcto – Cratylus

+0

1) sí, esta es mi observación. Para 2), no estoy seguro de si esto es un comportamiento previsto o un error, es solo una suposición de cómo explicar tanto tu como mi observación. –

+0

@Paulo: descubrí que el TrustManager real utilizado es 'X509TrustManagerImpl'. Aquí http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-sun/security/sun/security/ssl/X509TrustManagerImpl.java.java-doc.htm dice que esta clase tiene una lógica mínima. ¿Puedo estar utilizando el TrustManager incorrecto? – Cratylus

2

Creo que JSSE de IBM comprueba la caducidad mientras que la de Sun no.

+0

¿Crees que esto es un error, o lo diseñaron así en SUN? Desde mi punto de vista, el comportamiento es al menos contrario a la intuición. – Cratylus

+0

Parece ser deliberado. Creo que la intención era que compruebes el vencimiento en un oyente apretón de manos si crees que es importante. – EJP

5

He tenido un problema similar yo mismo al reemplazar checkServerTrusted.

Resulta que si necesita verificar la caducidad puede llamar al X509Certificate.checkValidity() y arrojará una CertificateExpiredException o una CertificateNotYetValidException. Ambos extienden la CertificateException para que puedan ser lanzados felizmente por checkServerTrusted.

Para resolver su problema podría implementar un nuevo X509TrustManager que crea la instancia original en su constructor, implementa todos los métodos como las llamadas a la instancia original, y añade una llamada a checkValidity para cada certificado de certs[] dentro checkServerTrusted.

Cuestiones relacionadas