2011-05-26 20 views
15

Estoy tratando de validar un certificado contra java key store y este es el código que estoy utilizando es el siguiente. Si se completa con éxito entonces supongo que la validación se ha realizado correctamente, de lo contrario, si se lanza una excepción, la validación falla. Mi preocupación es:Validar certificados X509 con Java APis

¿El código siguiente es válido para validar un certificado? Como en, ¿hay algo que me falta aquí (como verificar los datos firmados por la computadora que me envía el certificado?)? 2. ¿Debería verificarse la firma contenida en el certificado? Si es así, ¿cómo?

¡Gracias de antemano por la respuesta! Pradeep

// To check the validity of the dates 
cert.checkValidity(); 
//Check the chain 
CertificateFactory cf = CertificateFactory.getInstance("X.509"); 
List<X509Certificate> mylist = new ArrayList<X509Certificate>();   
mylist.add(cert); 
CertPath cp = cf.generateCertPath(mylist); 
PKIXParameters params = new PKIXParameters(getTrustStore()); 
params.setRevocationEnabled(false); 
CertPathValidator cpv = 
     CertPathValidator.getInstance(CertPathValidator.getDefaultType()); 
PKIXCertPathValidatorResult pkixCertPathValidatorResult = 
     (PKIXCertPathValidatorResult) cpv.validate(cp, params); 
+0

¿Por qué? JSSE ya hace todo esto por ti. – EJP

+0

@EJP, ¿pueden explicar cómo JSSE hace esto? Gracias. – user674669

Respuesta

0

Lo que está haciendo aquí está verificando si un certificado (en su ejemplo cert) ha sido firmado (directamente) por cualquiera de los de confianza de CA en el almacén de confianza.
Además, comprueba la caducidad pero no se realiza ninguna comprobación de revocación.
Por lo tanto, si el cert no ha sido firmado por ninguna de las CA confiables, recibirá una excepción.
Así que el código es suficiente para verificar si cert ha sido firmado por cualquiera de las entidades emisoras de confianza


Si usted se refiere a la autenticación del servidor, entonces el código en el post no es suficiente.
Este código simplemente verifica que un certificado específico esté firmado por una CA de confianza.
No tiene ninguna indicación si la "entidad" que le envía este certificado es realmente el propietario del certificado (es decir, posee la clave privada asociada con este certificado).
Esto es parte de la autenticación SSL, donde, p. el cliente envía el mensaje ClientKeyExchange encriptado con la clave pública del servidor remoto y está seguro de que si la otra parte es falsa, no será posible descifrar el mensaje

+0

¡Gracias por la respuesta rápida! ¿Es la pieza de código anterior suficiente para validar el certificado en sí? Quiero decir, si obtengo este certificado de un servidor y realizo los controles anteriores, ¿puedo suponer con seguridad que el certificado del servidor es válido y el servidor es quien dice ser? Gracias, su ayuda es muy apreciada. – user771870

+0

Respuesta actualizada. Espero que esto ayude – Cratylus

+0

Eso ayuda. Estoy tratando de implementar la autenticación del servidor para SSH. Entonces, una vez que obtengo el certificado del servidor durante el intercambio inicial, intento validarlo para asegurarme de que el servidor no es falso y realizar el procedimiento de validación de manera similar a como SSL lo hace. Entonces, ¿eso significaría que SSH se encargaría de la autenticación del servidor durante el intercambio de claves (antes de los intercambios de certificados) y todo lo que tengo que hacer es asegurarme de que el certificado sea válido? Gracias por la respuesta y mis disculpas si estas preguntas parecen estúpidas. Acabo de comenzar a buscar en los flujos de trabajo SSH :) – user771870

6

Normalmente, un certificado será emitido por una autoridad emisora ​​intermedia, no es una autoridad "raíz" (que es todo lo que debería estar en su tienda de confianza). La mayoría de los protocolos fomentan el envío de una "cadena" de certificados, no solo el certificado de la entidad.

Debe agregar todos los certificados intermedios para poder formar una cadena completa.

Para asegurarse de que el certificado sigue siendo válido, no debe deshabilitar las comprobaciones de revocación. Si no desea recuperar una CRL (que puede ser grande), el emisor puede ofrecer soporte OCSP. Pero esto debe habilitarse en el tiempo de ejecución de Java estableciendo ciertas propiedades del sistema.

Si el validador de ruta regresa exitosamente, no necesita verificar nada más. Si el certificado no es válido, se generará una excepción.

Además, no es necesaria una comprobación explícita de la fecha de validez. Esto ocurre durante la validación (usando la hora actual, a menos que especifique una hora a través del PKIXParameters).


Para una discusión más extensa de validación, incluyendo código de ejemplo, see a previous answer of mine.

+0

¡Gracias por la respuesta! ¿Quiere decir que tengo que agregar todos los certificados intermedios a la lista de certificados (mylist.add (cert);) y luego crear una cadena usando CertPath? ¡Gracias! – user771870

+0

Sí, eso es correcto. – erickson

+0

¡Gracias por la respuesta! – user771870

2

Si está satisfecho con los ajustes de seguridad por defecto (ya que serían utilizados por el impago SSLContext), se podría construir una X509TrustManager independientemente de SSL/TLS y use si para verificar su certificado de forma independiente.

Se vería así:

TrustManagerFactory trustManagerFactory = 
    TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
trustManagerFactory.init((KeyStore)null); 
// you could use a non-default KeyStore as your truststore too, instead of null. 

for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) { 
    if (trustManager instanceof X509TrustManager) { 
     X509TrustManager x509TrustManager = (X509TrustManager)trustManager; 
     x509TrustManager.checkServerTrusted(...); 
    } 
} 

(También debe verificar la identidad del servidor y el partido de certificados, consulte RFC 6125 (Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS)).)

+1

Uh, ¿qué entra en '...'? –

+0

@PaulDraper primer parámetro es la matriz de X509Certificate, el segundo parámetro es el algoritmo de intercambio de claves (por ejemplo, "RSA"), consulte también el Javadoc para X509TrustManager https://docs.oracle.com/javase/7/docs/api/javax /net/ssl/X509TrustManager.html –

+1

Tenga en cuenta que este código no generará ninguna excepción si TrustManagerFactory no tiene trustManager y acepta el certificado. Eché un vistazo al Javadoc para TrustManagerFactory y creo que esto podría suceder si de alguna manera tu Keystore predeterminado no contiene certificados X509 para CA. Para estar más seguro que lamentar, cambiaría el código para lanzar una excepción si el bucle for no encontró un X509TrustManager. –

Cuestiones relacionadas