una - porque aparece aplicacion bloqueada por la seguridad de java
Análisis y validación de certificados Java X509 (1)
Para referencia futura, publicaré la respuesta a mi propia pregunta (en parte al menos)
Las comprobaciones de OCSP y CRL se implementan en la implementación estándar de Java y no hay necesidad de código personalizado u otros proveedores (BC, ..). Ellos están desactivados por defecto.
Para habilitar esto, al menos debes establecer dos parámetros:
(PKIXParameters or PKIXParameterBuilder) params.setRevocationEnabled(true);
Security.setProperty("ocsp.enable", "true");
Esto activará la comprobación de OCSP cuando intente validar la ruta del certificado (PKIXCertPathValidatorResult.validate ()).
Cuando desee agregar el cheque alternativo para CRL si no hay OCSP disponible, agregue una propiedad adicional:
System.setProperty("com.sun.security.enableCRLDP", "true");
Muchos de mis problemas están sucediendo debido al hecho de que tengo que admitir diferentes formatos de certificados (PKCS7, PEM). Mi implementación funciona bien para PEM, pero como PKCS7 NO guarda el orden de los certificados en la cadena, 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);
Espero que esto también sea útil para otras personas, tal vez alguien pueda arrojar luz sobre cómo encontrar el certificado objetivo en una lista PKCS7 desordenada.
Intento procesar los certificados X509 en varios pasos y encontrarme con un par de problemas. Soy nuevo en JCE, así que no estoy completamente actualizado sobre todo.
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 dos líneas que no son necesarias 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 funciona bien a medida que trabajo con FileInputStream en lugar de BufferedInputStream para PCKS7, lo cual es bastante extraño, ¿no? Pero puedo vivir con eso.
El siguiente paso es validar estas cadenas de certificados. 1) Verifique si todos los certificados tienen una fecha válida (fácil) 2) Valide la cadena de certificados usando 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 realicé 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 funciona bien para mi certificado PEM, pero no para el certificado PCKS7 (mismo certificado, solo exportado en otro formato). java.security.cert.CertPathValidatorException: Path 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 de PEM, pero vamos a llamar a esta PREGUNTA 1;)
Lo que quería implementar después fue la comprobación de OCSP. Aparentemente si habilito OCSP usando: Security.setProperty ("ocsp.enable", "true"); y establecer params.setRevocationEnabled (true); debería poder encontrar la URL OCSP por sí misma, 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 un respondedor OCSP
Yendo más allá de esto, encontré una manera de recuperar la url OCSP del certificado utilizando AuthorityInfoAccessExtension y tal.
Pero después de configurar la URL OCSP manualmente en la propiedad ocsp.url, obtengo una java.security.cert.CertPathValidatorException: error de respuesta OCSP: NO AUTORIZADO
Parece que me faltan muchos pasos necesarios, mientras que muchas referencias en línea dicen que establecer la propiedad ocsp.enable debería ser todo lo que necesita hacer.
Quizás alguno de ustedes no puede guiarme a través del proceso un poco? Muéstrame dónde estoy completamente equivocado :)
El siguiente paso sería implementar controles 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!
EDITAR: Dado que no está recogiendo las propiedades por sí mismo, he estado intentando establecer todas las propiedades yo mismo usando lo 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));
Lo que da una excepción: java.security.cert.CertPathValidatorException: no se puede encontrar el certificado del respondedor (se establece utilizando las propiedades de seguridad OCSP).