14 Stimmen

PKCS12 Java Keystore von CA und Benutzerzertifikat in Java

Vor kurzem wurde mir die Aufgabe übertragen, ein Apple-Produkt (iPhone Configuration Utility) in Java nachzubilden. Einer der Abschnitte, bei dem ich nicht weiterkomme, ist ein Teil über Exchange ActiveSync. Dort können Sie ein Zertifikat aus Ihrem Schlüsselbund auswählen, das als Anmeldeinformationen für Ihr EAS-Konto verwendet werden soll. Nach einigen Nachforschungen habe ich herausgefunden, dass tatsächlich ein PKCS12-Keystore erstellt wird, in den der private Schlüssel des von mir ausgewählten Zertifikats eingefügt und in XML kodiert wird. So weit keine große Sache. Wenn ich mit Keychain Access eine .p12-Datei erstelle, wird sie ohne Probleme hochgeladen. Aber ich stoße auf ein Problem, wenn ich versuche, diese Datei nach Java zu übertragen.

Angenommen, ich exportiere eines der Zertifikate, die ich zuvor mit der .p12-Datei verwendet habe, als .cer-Datei (das ist das, was wir in der Umgebung erwarten). Wenn ich es nun in Java hochlade, erhalte ich ein Zertifikatsobjekt wie folgt...

KeyStore ks = java.security.KeyStore.getInstance("PKCS12");
ks.load(null, "somePassword".toCharArray());

CertificateFactory cf = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());
java.security.cert.Certificate userCert  = cf.generateCertificate(new FileInputStream("/Users/me/Desktop/RecentlyExportedCert.cer"));

Aber wenn ich es versuche...

ks.setCertificateEntry("SomeAlias", userCert);

Ich verstehe die Ausnahme...

java.security.KeyStoreException: TrustedCertEntry not supported

Von den Zertifikaten gehe ich also zu den Schlüsseln über. Aber mit diesen Zertifikaten (ich habe auch das CA-Zertifikat) kann ich nur auf den öffentlichen Schlüssel zugreifen, nicht auf den privaten. Und wenn ich versuche, den öffentlichen Schlüssel wie folgt hinzuzufügen...

java.security.cert.Certificate[] chain = {CACert};
ks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain);

Ich verstehe...

java.security.KeyStoreException: Private key is not stored as PKCS#8 EncryptedPrivateKeyInfo: java.io.IOException: DerValue.getOctetString, not an Octet String: 3

Jetzt bin ich also hier. Hat jemand eine Idee, wie man einen privaten Schlüssel aus einer .cer Datei in einen PKCS12 Keystore in Java bekommt? Bin ich überhaupt auf dem richtigen Weg?

Vielen Dank im Voraus!

18voto

Bruno Punkte 114719

Das PKCS#12-Format ist für die Speicherung eines privaten Schlüssels in Verbindung mit einer Zertifikatskette gedacht, und beide sind erforderlich (auch wenn Sie möglicherweise nicht die gesamte Kette benötigen). Obwohl das PKCS12 Keystore-Typ eignet sich gut für die Abbildung dieses Formats auf eine Java KeyStore Aus diesem Grund wird nicht alles unterstützt.

In Ihrem ersten Versuch versuchen Sie, ein Zertifikat allein zu speichern, was nicht funktionieren wird.

Was Sie in Ihrem zweiten Versuch tun wollen ( ks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain) ) ist es, einen öffentlichen Schlüssel anstelle eines privaten Schlüssels zu verwenden (siehe KeyStore#setKeyEntry ).

.cer Datei sind in der Regel nur für Zertifikate und nicht für private Schlüssel gedacht (obwohl die Erweiterung natürlich letztlich nur ein Hinweis ist). Wenn Sie Ihre .cer Datei von Schlüsselbund Access.app erhalten Sie den privaten Schlüssel nicht mit (das ist das, was die .p12 Exportformat ist für).

EDITAR über KeychainStore:

Wenn der Grund für diese Konvertierung letztendlich darin besteht, auf private Schlüssel und Zertifikate zuzugreifen, die sich bereits im Schlüsselbund befinden, können Sie diese aus dem Verzeichnis KeychainStore direkt:

KeyStore ks = KeyStore.getInstance("KeychainStore", "Apple");
ks.load(null, "-".toCharArray());

Dazu ein paar Anmerkungen:

  • Für die Verwendung des privaten Schlüssels genügt jedes beliebige, nicht leere Passwort (z. B. "-".toCharArray() ), da der Zugriff durch den Sicherheitsdienst des Betriebssystems abgefragt wird (wie bei anderen Anwendungen auch).
  • Soweit mir bekannt ist, gibt es immer noch einen Fehler und es erlaubt nur den Zugang zu einem privaten Schlüssel/Zertifikatspaar (auch wenn mehrere Paare von privaten Schlüsseln/Zertifikaten im Schlüsselbund vorhanden sind)

3voto

Fico Punkte 599

http://www.docjar.com/html/api/org/bouncycastle/jce/examples/PKCS12Example.java.html

So fügen Sie ein Zertifikat mit einem zugehörigen privaten Schlüssel zu einem PKCS12-Keystore hinzu. Wenn Sie die Client-Authentifizierung verwenden, muss der Keystore auch den privaten Schlüssel enthalten; in diesem Fall verwenden Sie KeyStore.getInstance("PKCS12").

Wenn Sie keine Client-Authentifizierung, sondern nur eine Server-Authentifizierung verwenden (und der private Schlüssel nicht zum Schlüsselspeicher hinzugefügt wird, da er dem Server gehört), ist es besser, die Funktion KeyStore.getInstance("JKS") zu verwenden, dann können Sie mehrere Zertifikate mit einem Alias zu diesem einen Keystore hinzufügen.

Wenn Sie PKCS12 verwenden, können Sie, soweit ich weiß, nur 1 Zertifikat hinzufügen (Sie müssen die gesamte Zertifikatskette hinzufügen), das mit dem privaten Schlüssel verknüpft ist, den Sie für dieses Zertifikat verwenden möchten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X