2012-04-06 18 views
12

Ich versuche, X509-Zertifikate in mehreren Schritten zu verarbeiten und in ein paar Probleme zu laufen. Ich bin neu bei JCE, also bin ich noch nicht ganz auf dem Laufenden.Java X509 Zertifikat analysieren und validieren

Wir wollen verschiedene X509-Zertifikate basierend auf verschiedenen Kodierungen (PEM, DER und PCKS7) analysieren können. Ich habe das gleiche Zertifikat von https://belgium.be im PEM- und PCKS7-Format mit FireFox (Zertifikat inklusive Kette) exportiert. Ich habe aus paar Zeilen hinterlassen, die nicht für die Fragen

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; 
    } 

Fein benötigt Dieser Code arbeitet aslong als ich mit einem Fileinputstream anstelle eines BufferedInputStream für PCKS7 arbeiten, was ziemlich merkwürdig ist schon denke ich? Aber ich kann damit leben.

Der nächste Schritt besteht darin, diese Zertifikatsketten zu validieren. 1) Überprüfen Sie, ob alle Zertifikate ein gültiges Datum haben (einfach) 2) Überprüfen Sie die Zertifikatskette mit OCSP (und Fallback auf CRL, wenn keine OCSP-URL im Zertifikat gefunden wird). Hier bin ich mir nicht ganz sicher, wie ich damit umgehen soll.

Ich benutze die Sun JCE, aber es scheint, dass nicht so viel Dokumentation (in Beispielen) dafür vorhanden ist?

Ich machte zuerst eine einfache Implementierung, die nur die Kette überprüft, ohne die OCSP/CRL-Prüfungen zu durchlaufen.

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; 
} 

Dies funktioniert für meine PEM-Zertifikat in Ordnung, aber nicht für das PCKS7 Zertifikat (gleiche certifcate, nur in einem anderen Format exportiert). java.security.cert.CertPathValidatorException: Der Pfad wird nicht mit einem der Vertrauensanker verknüpft.

Der einzige Unterschied, den ich sehen kann, ist, dass die Reihenfolge, in der der CertPath gebildet wird, nicht die gleiche ist? Ich war nicht in der Lage, herauszufinden, was schief ging, also ließ ich das für jetzt und ging weiter mit dem PEM-Zertifikat, aber rufen Sie diese Frage 1)

Was ich später implementieren wollte war die OCSP-Prüfung. Offenbar, wenn ich OCSP aktivieren mit: Security.setProperty ("ocsp.enable", "true"); und einstellen params.setRevocationEnabled (true); sollte es in der Lage sein, die OCSP-URL selbst zu finden, aber das scheint nicht der Fall zu sein. Was soll die Standardimplementierung tun (FRAGE 2)? java.security.cert.CertPathValidatorException: Muss die Position eines OCSP-Responder

Vorbei dies angeben, fand ich einen Weg, um die OCSP-URL aus dem Zertifikat mit AuthorityInfoAccessExtension und so abzurufen.

aber nach der OCSP-URL manuell in der ocsp.url-Eigenschaft, Ich erhalte einen java.security.cert.CertPathValidatorException: OCSP-Antwort-Fehler: UNAUTHORIZED

Es scheint, als wäre ich ein fehlt bin Viele notwendige Schritte, während viele Online-Referenzen sagen, die Einstellung der ocsp.enable Eigenschaft sollte alles sein, was Sie tun müssen?

Vielleicht kann jeder von euch Whizkids mich durch den Prozess ein wenig führen?Zeig mir, wo ich völlig falsch bin :)

Der nächste Schritt wäre die Implementierung von CRL-Checks, wenn kein OCSP gefunden wurde, wenn jemand irgendein Beispiel aufzeigen könnte oder mir eine Dokumentation darüber zeigen könnte, wäre es auch sehr geschätzt!

Danke!

EDIT: Da es nicht die Eigenschaften auf seine eigene Aufnehmen, ich habe alle Eigenschaften selbst zu setzen versucht, mit dem folgenden:

// 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)); 

, die eine Ausnahme gibt: java. security.cert.CertPathValidatorException: Das Zertifikat des Responders wurde nicht gefunden (festgelegt mit den OCSP-Sicherheitseigenschaften).

+0

OSCPChecker scheint dies in der getOCSPServerURI-Methode zu tun: 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

Was ist 'cf' in Ihrem Beispiel? – spy

+0

Es ist eine lange Zeit, aber ich würde sagen https://docs.oracle.com/javase/7/docs/api/java/security/cert/CertificateFactory.html –

Antwort

15

Für die Zukunft werde ich die Antwort auf meine eigene Frage posten (teilweise atleast)

OCSP und CRL-Prüfungen werden in der Standard-Java-Implementierung bereits umgesetzt, und es gibt keine Notwendigkeit für benutzerdefinierten Code oder andere Anbieter (BC , ..). Sie sind standardmäßig deaktiviert.

Um dies zu ermöglichen, haben Sie zwei Parameter atleast gesetzt:

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

Diese OCSP aktivieren wird überprüft, wenn Sie versuchen, den Zertifikatspfad (PKIXCertPathValidatorResult.validate()) zu validieren.

Wenn Sie die Rückfallprüfung für CRL hinzufügen möchten, wenn kein OCSP verfügbar ist, fügen Sie eine aditional Eigenschaft:

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

Viele meiner Probleme aufgrund der Tatsache geschehen, dass ich anderes Zertifikat unterstützen haben Formate (PKCS7, PEM). Meine Implementierung arbeitet für PEM in Ordnung, aber da PKCS7 dies nicht der Fall Reihenfolge der Zertifikate in der Kette sparen ist ein bisschen schwieriger (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); 

Hoffen, dass dieses nützliche Hinweise für andere Menschen als auch sein wird, vielleicht jemand kann Wie finde ich das Zielzertifikat in einer ungeordneten PKCS7-Liste?

Verwandte Themen