Wie liste und exportiere ich einen privaten Schlüssel aus einem Keystore?Wie listet/exportiert ich private Schlüssel aus einem Schlüsselspeicher?
Antwort
Ein Teil des Codes aus Beispiel Depot ursprünglich für alle Aliase in einem Schlüsselspeicher-Eintrag:
// Load input stream into keystore
keystore.load(is, password.toCharArray());
// List the aliases
Enumeration aliases = keystore.aliases();
for (; aliases.hasMoreElements();) {
String alias = (String)aliases.nextElement();
// Does alias refer to a private key?
boolean b = keystore.isKeyEntry(alias);
// Does alias refer to a trusted certificate?
b = keystore.isCertificateEntry(alias);
}
den Export von privaten Schlüsseln auf dem Sun forums vor ein paar Monaten kam, und u:turingcompleter kam mit einer DumpPrivateKey-Klasse zum Einfügen in Ihre App.
Hinweis: Dies verwenden Sun-Paket, which is a "bad thing".
Wenn Sie apache commons code herunterladen können, hier ist eine Version, die ohne Warnung kompilieren:
javac -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey.java
und wird das gleiche Ergebnis:
import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
//import sun.misc.BASE64Encoder;
import org.apache.commons.codec.binary.Base64;
public class DumpPrivateKey {
/**
* Provides the missing functionality of keytool
* that Apache needs for SSLCertificateKeyFile.
*
* @param args <ul>
* <li> [0] Keystore filename.
* <li> [1] Keystore password.
* <li> [2] alias
* </ul>
*/
static public void main(String[] args)
throws Exception {
if(args.length < 3) {
throw new IllegalArgumentException("expected args: Keystore filename, Keystore password, alias, <key password: default same tha
n keystore");
}
final String keystoreName = args[0];
final String keystorePassword = args[1];
final String alias = args[2];
final String keyPassword = getKeyPassword(args,keystorePassword);
KeyStore ks = KeyStore.getInstance("jks");
ks.load(new FileInputStream(keystoreName), keystorePassword.toCharArray());
Key key = ks.getKey(alias, keyPassword.toCharArray());
//String b64 = new BASE64Encoder().encode(key.getEncoded());
String b64 = new String(Base64.encodeBase64(key.getEncoded(),true));
System.out.println("-----BEGIN PRIVATE KEY-----");
System.out.println(b64);
System.out.println("-----END PRIVATE KEY-----");
}
private static String getKeyPassword(final String[] args, final String keystorePassword)
{
String keyPassword = keystorePassword; // default case
if(args.length == 4) {
keyPassword = args[3];
}
return keyPassword;
}
}
Sie können es wie so verwenden:
java -classpath .:commons-codec-1.4/commons-codec-1.4.jar DumpPrivateKey $HOME/.keystore changeit tomcat
Vor allem, sei vorsichtig! All Ihre Sicherheit hängt von der & hellip; er & hellip; Privatsphäre Ihrer privaten Schlüssel. In Keytool ist kein Schlüsselexport eingebaut, um eine versehentliche Offenlegung dieses sensiblen Materials zu vermeiden. Sie sollten daher zusätzliche Sicherheitsvorkehrungen in Erwägung ziehen, um Ihre exportierten Schlüssel zu schützen.
Hier finden Sie einige einfache Code, den Sie unverschlüsselt PKCS # 8 PrivateKeyInfo gibt, die von OpenSSL verwendet werden können (die -nocrypt
Option seiner pkcs8 utility sehen):
KeyStore keys = ...
char[] password = ...
Enumeration<String> aliases = keys.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if (!keys.isKeyEntry(alias))
continue;
Key key = keys.getKey(alias, password);
if ((key instanceof PrivateKey) && "PKCS#8".equals(key.getFormat())) {
/* Most PrivateKeys use this format, but check for safety. */
try (FileOutputStream os = new FileOutputStream(alias + ".key")) {
os.write(key.getEncoded());
os.flush();
}
}
}
Wenn Sie andere Formate benötigen, können Sie ein verwenden KeyFactory, um eine transparente Schlüsselspezifikation für verschiedene Schlüsseltypen zu erhalten. Dann können Sie beispielsweise den privaten Exponenten eines privaten RSA-Schlüssels erhalten und in Ihrem gewünschten Format ausgeben. Das wäre ein gutes Thema für eine Folgefrage.
Wenn Sie es nicht programmatisch machen müssen, sondern nur Ihre Schlüssel verwalten wollen, dann verwende ich seit langem das kostenlose KeyMan-Tool von IBM. Sehr schön für das Exportieren eines privaten Schlüssels in eine PFX-Datei (dann können Sie OpenSSL leicht verwenden, um es zu manipulieren, es zu extrahieren, Pwds zu ändern usw.).
Keystore- auswählen, den privaten Schlüssel Eintrag auswählen, dann File-> Save in eine PKCS12-Datei (* .pfx, in der Regel). Anschließend können Sie den Inhalt mit:
$ openssl pkcs12 -in mykeyfile.pfx -info
Der KeyMan-Seitenlink wurde in https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=6fb00498-f6ea-4f65-bf0c-adc5bd0c5fcc geändert (nie endende URL 404/Neuschreibungen!) – manikanta
Der Download-Link befindet sich in der oberen rechten Ecke der Seite. Sie benötigen eine IBM ID ... Sie können eine kostenlos erstellen. Ich entschied mich, die erste Zip-Option herunterzuladen. Damit es unter Windows funktioniert, müssen Sie entweder in C: \ Programme \ IBM \ BlueZ \ KeyMan entpacken, oder Sie müssen die ZIP-Datei entpacken, wo immer Sie möchten, und die erste Zeile von km.bat ändern, um den Pfad zu dem Ordner zu erhalten enthält km.bat. Führen Sie dann km.bat ohne Argumente aus. Sollte so lange arbeiten, wie Java auf deinem Weg ist. – ArtOfWarfare
Sie können einen privaten Schlüssel aus einem Schlüsselspeicher mit Java6 und OpenSSL extrahieren. Dies hängt davon ab, dass sowohl Java als auch OpenSSL PKCS # 12-formatierte Keystores unterstützen. Um die Extraktion durchzuführen, verwenden Sie zuerst keytool
, um in das Standardformat zu konvertieren. Stellen Sie sicher, dass Sie verwenden das gleiche Passwort für beide Dateien (Passwort des privaten Schlüssels, nicht das Keystore-Passwort) oder Sie erhalten ungerade Fehler später im zweiten Schritt.
keytool -importkeystore -srckeystore keystore.jks \
-destkeystore intermediate.p12 -deststoretype PKCS12
Als nächstes verwenden OpenSSL die Extraktion PEM zu tun:
openssl pkcs12 -in intermediate.p12 -out extracted.pem -nodes
Sie sollten diese PEM-Datei leicht genug zu handhaben können; Es ist reiner Text mit einem unverschlüsselten privaten Schlüssel und Zertifikaten darin (in einem ziemlich offensichtlichen Format).
Wenn Sie dies tun, achten Sie darauf, die erstellten Dateien sicher zu halten. Sie enthalten geheime Anmeldeinformationen. Nichts wird Sie warnen, wenn Sie sie nicht richtig sichern können. Die einfachste Methode, sie zu sichern, besteht darin, all dies in einem Verzeichnis zu tun, das für niemanden außer dem Benutzer Zugriffsrechte besitzt. Und setzen Sie niemals Ihr Passwort in die Befehlszeile oder in Umgebungsvariablen; Es ist zu leicht für andere Benutzer zu greifen.
Die Hintergrundgeschichte: Benötigt heute, damit wir zwischen einem Java-Webservice-Client und einem Java-Webservice-Server einen Drahtshark legen konnten; Es hat wie ein Traum funktioniert und wir haben unseren Bug behoben (ein Config-Problem bei der Handhabung von Cookies). Ich dachte, ich würde teilen, weil es praktisch ist, keinen Code schreiben zu müssen, um so etwas zu tun, und viele Leute haben bereits die benötigten Tools installiert, im Gegensatz zu den anderen Antworten. –
Ehrfürchtige Post. Gut gemacht, mein Herr! –
danke danke danke !!! –
für Android Entwicklung, Schlüsselspeicher in Eclipse ADT in öffentlichen Schlüssel und einen privaten Schlüssel in SignApk.jar verwendet erstellt konvertieren:
Export privaten Schlüssel:
keytool.exe -importkeystore -srcstoretype JKS -srckeystore my-release-key.keystore -deststoretype PKCS12 -destkeystore keys.pk12.der
openssl.exe pkcs12 -in keys.pk12.der -nodes -out private.rsa.pem
bearbeiten private.rsa.pem und verlassen "----- PRIVATE KEY ----- BEGIN" auf "----- END PRIVATE KEY -----" Absatz, dann gilt:
openssl.exe base64 -d -in private.rsa.pem -out private.rsa.der
Export öffentlichen Schlüssel:
keytool.exe -exportcert -keystore my-release-key.keystore -storepass <KEYSTORE_PASSWORD> -alias alias_name -file public.x509.der
Zeichen apk:
java -jar SignApk.jar public.x509.der private.rsa.der input.apk output.apk
Ich habe Ihren Vorschlag versucht, aber es schlägt bei dem ersten openssl-Befehl fehl - es meldet Entschlüsselungsfehler. Der ursprüngliche Schlüsselspeicher, mit dem ich getestet habe, ist Routinen, die mit jarsigner verwendet werden. Der Fehler ist sowohl unter Cygwins Tools als auch unter Fedoras Tools passiert. – mah
Es funktionierte für mich, ich suchte im ganzen Web nach dieser Lösung, danke Diyism –
Hier ist eine kürzere Version des obigen Code in Groovy. Auch verfügt über eine integrierte in Base64-Codierung:
import java.security.Key
import java.security.KeyStore
if (args.length < 3)
throw new IllegalArgumentException('Expected args: <Keystore file> <Keystore format> <Keystore password> <alias> <key password>')
def keystoreName = args[0]
def keystoreFormat = args[1]
def keystorePassword = args[2]
def alias = args[3]
def keyPassword = args[4]
def keystore = KeyStore.getInstance(keystoreFormat)
keystore.load(new FileInputStream(keystoreName), keystorePassword.toCharArray())
def key = keystore.getKey(alias, keyPassword.toCharArray())
println "-----BEGIN PRIVATE KEY-----"
println key.getEncoded().encodeBase64()
println "-----END PRIVATE KEY-----"
Ein anderer, weniger konventioneller aber wohl einfacher Weg, dies zu tun mit JXplorer ist. Obwohl dieses Tool zum Durchsuchen von LDAP-Verzeichnissen entwickelt wurde, verfügt es über eine benutzerfreundliche GUI zum Bearbeiten von Schlüsselspeichern. Eine solche Funktion auf der GUI kann private Schlüssel aus einem JKS-Keystore exportieren.
Diese Frage kam auf Stack Sicherheit auf, einen der Vorschläge war Keystore explorer
Nachdem es zu benutzen, nur versucht, es funktioniert wirklich gut und ich kann es sehr empfehlen.
Ein weiteres großartiges Werkzeug ist Keystor Explorer: http://keystore-explorer.sourceforge.net/
Das hat super funktioniert. Ich hatte einen Kunden, der eine Zertifikatsanforderung mithilfe der Tomcat-Anweisungen erstellte, sodass der private Schlüssel im Keystore installiert wurde. Ich brauchte es um mit Apache zu arbeiten. – ScArcher2
Ein Jahr und ein bisschen später und du hast das Problem eines anderen gelöst (d. H. Meins). Gut gemacht! :) –
Eigentlich sollte dies mit einem zusätzlichen Parameter aktualisiert werden: [3] Key-Passwort und die Zeile 'Key key = ks.getKey (args [2], args [1]. ToCharArray());' sollte 'lesen Schlüssel key = ks.getKey (args [2], args [3]. ToCharArray()); '. Der ursprüngliche Code geht davon aus, dass das KEY-Passwort mit dem KEYSTORE-Passwort identisch ist, wenn sie nicht unbedingt identisch sind. – REW