2012-04-06 24 views
12

Estoy tratando de procesar los certificados X509 en varios pasos y encontrando un par de problemas. Soy nuevo en JCE, así que no estoy completamente actualizado sobre todo.Java X509 Certificado de análisis y validación

Queremos ser capaces de analizar varios certificados X509 diferentes basados ​​en diferentes codificaciones (PEM, DER y PCKS7). He exportado el mismo certificado de https://belgium.be en formato PEM y PCKS7 usando FireFox (certificado que incluye la cadena). He dejado par de líneas que no son necesarios para las preguntas

public List<X509Certificate> parse(FileInputStream fis) { 
    /* 
    * Generate a X509 Certificate initialized with the data read from the inputstream. 
    * NOTE: Generation fails when using BufferedInputStream on PKCS7 certificates. 
    */ 
    List<X509Certificate> certificates = null; 
     log.debug("Parsing new certificate."); 
     certificates = (List<X509Certificate>) cf.generateCertificates(fis); 
    return certificates; 
    } 

Este código está trabajando bien aslong ya que trabajo con un FileInputStream en lugar de un BufferedInputStream para PCKS7, lo cual es bastante extraño ya que pienso? Pero puedo vivir con eso.

El siguiente paso es validar estas cadenas de certificados. 1) Compruebe si todos los certificados tienen una fecha válida (fácil) 2) Valide la cadena de certificados utilizando OCSP (y repliegue a CRL si no se encuentra una URL OCSP en el certificado). Aquí es donde no estoy completamente seguro de cómo manejar esto.

Estoy usando Sun JCE, pero parece que no hay mucha documentación disponible (en ejemplos) para esto?

Primero hice una implementación simple que solo verifica la cadena sin pasar por las comprobaciones OCSP/CRL.

private Boolean validateChain(List<X509Certificate> certificates) { 
    PKIXParameters params; 
    CertPath certPath; 
    CertPathValidator certPathValidator; 
    Boolean valid = Boolean.FALSE; 

    params = new PKIXParameters(keyStore); 
    params.setRevocationEnabled(false); 

    certPath = cf.generateCertPath(certificates); 
    certPathValidator = CertPathValidator.getInstance("PKIX"); 

    PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) 
    certPathValidator.validate(certPath, params); 

     if(null != result) { 
     valid = Boolean.TRUE; 
     } 
    return valid; 
} 

Esto es trabajar bien para mi certificado PEM, pero no para el certificado PCKS7 (Certifcate misma, sólo se exporta en otro formato). java.security.cert.CertPathValidatorException: La ruta no se encadena con ninguno de los anclajes de confianza.

La única diferencia que puedo ver es que el orden en que se forma CertPath no es el mismo? No pude averiguar qué estaba pasando mal, así que dejé esto por el momento y continué con el certificado PEM, pero vamos a llamar a esta PREGUNTA 1;)

Lo que quería implementar después fue la verificación OCSP. Aparentemente si habilito OCSP usando: Security.setProperty ("ocsp.enable", "true"); y establecer params.setRevocationEnabled (true); debería ser capaz de encontrar la URL OCSP por sí mismo, pero ese no parece ser el caso. ¿Qué se supone que debe hacer la implementación estándar (PREGUNTA 2)? java.security.cert.CertPathValidatorException: Debe especificar la ubicación de una respuesta de OCSP

Yendo más allá de esto, he encontrado una manera de recuperar la URL de OCSP a partir del certificado utilizando AuthorityInfoAccessExtension y tal.

Pero después de establecer la URL de OCSP de forma manual en la propiedad ocsp.url, Recibo un java.security.cert.CertPathValidatorException: OCSP respuesta de error: no autorizado

Parece que me estoy perdiendo una Muchos de los pasos necesarios, mientras que muchas referencias en línea dicen que la configuración de la propiedad ocsp.enable debería ser todo lo que necesita hacer.

Quizás alguno de ustedes no pueda guiarme a través del proceso un poco?Muéstrame dónde estoy completamente equivocado :)

El siguiente paso sería implementar verificaciones de CRL si no se encontraba OCSP, si alguien pudiera señalar algún ejemplo o mostrarme alguna documentación sobre esto, ¡también sería muy apreciado!

Gracias!

EDIT: ya que no está recogiendo las propiedades por su cuenta, he estado tratando de establecer todas las propiedades a mí mismo utilizando la siguiente:

// Activate OCSP 
     Security.setProperty("ocsp.enable", "true"); 
     // Activate CRLDP -- no idea what this is 
     Security.setProperty("com.sun.security.enableCRLDP", "true"); 

     X509Certificate target = (X509Certificate) certPath.getCertificates().get(0); 
     Security.setProperty("ocsp.responderURL","http://ocsp.pki.belgium.be/"); 
     Security.setProperty("ocsp.responderCertIssuerName", target.getIssuerX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSubjectName", target.getSubjectX500Principal().getName()); 
     Security.setProperty("ocsp.responderCertSerialNumber", target.getSerialNumber().toString(16)); 

que da una excepción: java. security.cert.CertPathValidatorException: no se puede encontrar el certificado del respondedor (establecido utilizando las propiedades de seguridad OCSP).

+0

OSCPChecker parece hacer esto en el método getOCSPServerURI: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/provider/certpath/OCSPChecker .java # OCSPChecker.getOCSPServerURI% 28sun.security.x509.X509CertImpl% 2Cjava.lang.String% 29 –

+0

¿Qué es 'cf' en su ejemplo? – spy

+0

Ha pasado mucho tiempo, pero yo diría https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html –

Respuesta

15

Para referencia futura Voy a publicar la respuesta a mi propia pregunta (al menos parcialmente)

OCSP y CRL controles se implementan en la implementación estándar de Java ya y no hay necesidad de código personalizado o de otros proveedores (BC , ..). Ellos están desactivados por defecto.

Para permitir esto, usted tiene que establecer al menos dos parámetros:

(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true); 
Security.setProperty("ocsp.enable", "true"); 

Esto activará la comprobación OCSP cuando se está tratando de validar la ruta del certificado (PKIXCertPathValidatorResult.validate()).

Cuando se desea añadir el cheque de reserva para CRL si no hay OCSP está disponible, agregue una propiedad adicional:

System.setProperty("com.sun.security.enableCRLDP", "true"); 

Muchos de mis problemas están ocurriendo debido al hecho de que tengo que soportar diferentes certificado formatos (PKCS7, PEM). Mi aplicación funciona bien para PEM, pero desde PKCS7 NO guarda orden de los certificados de la cadena que es un poco más difícil (http://bugs.sun.com/view_bug.do?bug_id=6238093)

X509CertSelector targetConstraints = new X509CertSelector(); 

targetConstraints.setCertificate(certificates.get(0)); 
// Here's the issue for PKCS7 certificates since they are not ordered, 
// but I havent figured out how I can see what the target certificate 
// (lowest level) is in the incoming certificates.. 

PKIXBuilderParameters params = new PKIXBuilderParameters(anchors, targetConstraints); 

Esperamos que esto sea observaciones útiles para otras personas también, tal vez alguien puede arrojar luz sobre cómo encontrar el certificado objetivo en una lista PKCS7 desordenada?

Cuestiones relacionadas