Wie importiere ich ein vorhandenes X.509-Zertifikat und einen privaten Schlüssel in den Java-Keystore, um sie in SSL zu verwenden?

227

Ich habe dies in einer ActiveMQ-Konfiguration:

<sslContext>
        <sslContext keyStore="file:/home/alex/work/amq/broker.ks"  
 keyStorePassword="password" trustStore="file:${activemq.base}/conf/broker.ts" 
 trustStorePassword="password"/>
</sslContext>

Ich habe ein Paar X.509-Zertifikat und eine Schlüsseldatei.

Wie importiere ich diese beiden, um sie in SSL- und SSL + -Stomp-Connectors zu verwenden? Alle Beispiele, die ich googeln könnte, generieren den Schlüssel immer selbst, aber ich habe bereits einen Schlüssel.

Ich habe versucht

keytool -import  -keystore ./broker.ks -file mycert.crt

Dies importiert jedoch nur das Zertifikat und nicht die Schlüsseldatei und führt zu

2009-05-25 13:16:24,270 [localhost:61612] ERROR TransportConnector - Could not accept connection : No available certificate or key corresponds to the SSL cipher suites which are enabled.

Ich habe versucht, das Zertifikat und den Schlüssel zu verketten, habe aber das gleiche Ergebnis erzielt.

Wie importiere ich den Schlüssel?

Aleksandar Ivanisevic
quelle
1
Sie müssen tatsächlich ein bisschen Code schreiben, um dies zu tun, und die Details hängen vom Format des privaten Schlüssels ab, den Sie importieren möchten. Welches Format ist Ihr Schlüssel? Können Sie erklären, mit welchen Tools Sie den Schlüssel und das Zertifikat generiert haben, über die Sie verfügen?
Erickson
Informationen zu
bidirektionalem

Antworten:

73

Ob Sie es glauben oder nicht, Keytool bietet keine grundlegenden Funktionen wie das Importieren eines privaten Schlüssels in den Keystore. Sie können diese Problemumgehung ausprobieren mit PKSC12 Datei mit einem privaten Schlüssel zu einem Schlüsselspeicher zu verschmelzen.

Oder verwenden Sie einfach den benutzerfreundlicheren KeyMan von IBM für die Keystore-Behandlung anstelle von keytool.exe.

Matej
quelle
11
Laut der Antwort von CoverosGene unterstützt keytool es seit Java 6. Dies ist der Link, den er bereitgestellt hat
Houtman
Für das, was es wert ist, ist der beste Link bei all dem Lärm zu diesem Thema @ Matejs 'Workaround'-Link zu diesem Beitrag von 2008: cunning.sharp.fm/2008/06/importing_private_keys_into_a.html
cloudurfin
2
Ich folgte der Antwort von CoverosGene und es funktionierte.
Robert3452
1
KeyMan scheint mir nicht allzu benutzerfreundlich zu sein.
Missetäter
15
Defekter Link. Bitte geben Sie die Details der Lösung direkt in die Antwort ein :-(
lilalinux
535

Ich habe die folgenden zwei Schritte verwendet, die ich in den Kommentaren / Beiträgen gefunden habe, die in den anderen Antworten verlinkt sind:

Schritt eins: Konvertieren Sie das x.509-Zertifikat und den Schlüssel in eine pkcs12-Datei

openssl pkcs12 -export -in server.crt -inkey server.key \
               -out server.p12 -name [some-alias] \
               -CAfile ca.crt -caname root

Hinweis: Stellen Sie sicher, dass Sie ein Kennwort für die Datei pkcs12 eingeben. Andernfalls wird beim Importieren eine Nullzeigerausnahme angezeigt. (Falls jemand anderes diese Kopfschmerzen hatte). ( Danke Jocull! )

Anmerkung 2: Möglicherweise möchten Sie die -chainOption hinzufügen , um die vollständige Zertifikatkette beizubehalten. ( Danke Mafuba )

Schritt zwei: Konvertieren Sie die Datei pkcs12 in einen Java-Keystore

keytool -importkeystore \
        -deststorepass [changeit] -destkeypass [changeit] -destkeystore server.keystore \
        -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass some-password \
        -alias [some-alias]

Fertig

OPTIONAL Schritt Null: Erstellen Sie ein selbstsigniertes Zertifikat

openssl genrsa -out server.key 2048
openssl req -new -out server.csr -key server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Prost!

reto
quelle
12
Stellen Sie sicher, dass Sie ein Kennwort für die p12-Datei eingeben. Andernfalls wird beim Importieren eine Nullreferenzausnahme angezeigt. (Falls jemand anderes diese Kopfschmerzen hatte)
Jocull
9
In meinem Fall hat die Option in Schritt 1 -CAfile ca.crt -caname rootdie CA-Zertifikate nicht korrekt ausgegeben. Stattdessen habe ich-certfile concatenedCAFiles.pem
dcernahoschi
11
Vergessen Sie nicht, das -chainArgument mit openssl zu verwenden, um die vollständige Zertifikatkette in Ihre pfx / p12-Datei aufzunehmen, wenn Sie dies in Ihrem Schlüsselspeicher möchten.
Mafuba
3
In einer Windows-Umgebung pvk2pfx(ein Standard-VS-Tool, das in der VS- cmdEingabeaufforderung verfügbar ist ) wird ein .pfx--äquivalent zu a ausgegeben .p12. @ joculls Rat ist immer noch relevant; Geben Sie ein Passwort ein. Nicht opensslbenötigt.
Ben Mosher
9
Für Tomcat insbesondere ist es zwingend notwendig , dass die Schlüsselspeicher und die Schlüssel Passwörter gleich sind. Wenn Sie einen importieren, hat .p12der Schlüssel das Passwort des ursprünglichen .p12.Tomcat, mit dem er fehlschlägt java.security.UnrecoverableKeyException: Cannot recover key. Mit anderen Worten: Wenn Sie -deststorepass changeit -srcstorepass some-passwordmit unterschiedlichen Passwörtern ausführen müssen , müssen Sie -destkeypass changeit(mit demselben Passwort wie -deststorepass)
Slav
127

Keytool in Java 6 bietet folgende Funktionen: Importieren von privaten Schlüsseln in einen Java-Keystore mithilfe von Keytool

Hier sind die grundlegenden Details aus diesem Beitrag.

  1. Konvertieren Sie das vorhandene Zertifikat mit OpenSSL in ein PKCS12. Ein Passwort ist erforderlich, wenn Sie gefragt werden, oder der zweite Schritt wird sich beschweren.

    openssl pkcs12 -export -in [my_certificate.crt] -inkey [my_key.key] -out [keystore.p12] -name [new_alias] -CAfile [my_ca_bundle.crt] -caname root
  2. Konvertieren Sie den PKCS12 in eine Java-Keystore-Datei.

    keytool -importkeystore -deststorepass [new_keystore_pass] -destkeypass [new_key_pass] -destkeystore [keystore.jks] -srckeystore [keystore.p12] -srcstoretype PKCS12 -srcstorepass [pass_used_in_p12_keystore] -alias [alias_used_in_p12_keystore]
CoverosGene
quelle
4
Die Antwort von @reto enthält den Inhalt dieses Links.
Mafuba
4
Wie von @Mafuba angegeben, müssen Sie immer noch einen separaten pkcs12-Keystore mit einem Nicht-Java-Tool wie openssl erstellen. Dieser kann dann von keytool in einen jks-Speicher importiert werden, wie in der Antwort von reto angegeben.
Mister_Tom
Eine Sache, die dies zu einer guten Antwort macht, ist die Tatsache, dass die Eingabezertifikate in den Klammern klar angegeben sind.
Mr. Budris
FWIW, sollte die Ausgabe von Schritt 1 bereits benutzbar sein als Java - Schlüsselspeicher (so Schritt 2 möglicherweise nicht erforderlich - es sei denn , Sie tun müssen das CERT + Schlüssel in ein importieren vorhandenen Schlüsselspeicher) - wie bereits in einer früheren Antwort erwähnt von @ jaco0646
Janaka Bandara
9

Und einer mehr:

#!/bin/bash

# We have:
#
# 1) $KEY : Secret key in PEM format ("-----BEGIN RSA PRIVATE KEY-----") 
# 2) $LEAFCERT : Certificate for secret key obtained from some
#    certification outfit, also in PEM format ("-----BEGIN CERTIFICATE-----")   
# 3) $CHAINCERT : Intermediate certificate linking $LEAFCERT to a trusted
#    Self-Signed Root CA Certificate 
#
# We want to create a fresh Java "keystore" $TARGET_KEYSTORE with the
# password $TARGET_STOREPW, to be used by Tomcat for HTTPS Connector.
#
# The keystore must contain: $KEY, $LEAFCERT, $CHAINCERT
# The Self-Signed Root CA Certificate is obtained by Tomcat from the
# JDK's truststore in /etc/pki/java/cacerts

# The non-APR HTTPS connector (APR uses OpenSSL-like configuration, much
# easier than this) in server.xml looks like this 
# (See: https://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html):
#
#  <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
#                SSLEnabled="true"
#                maxThreads="150" scheme="https" secure="true"
#                clientAuth="false" sslProtocol="TLS"
#                keystoreFile="/etc/tomcat6/etl-web.keystore.jks"
#                keystorePass="changeit" />
#

# Let's roll:    

TARGET_KEYSTORE=/etc/tomcat6/foo-server.keystore.jks
TARGET_STOREPW=changeit

TLS=/etc/pki/tls

KEY=$TLS/private/httpd/foo-server.example.com.key
LEAFCERT=$TLS/certs/httpd/foo-server.example.com.pem
CHAINCERT=$TLS/certs/httpd/chain.cert.pem

# ----
# Create PKCS#12 file to import using keytool later
# ----

# From https://www.sslshopper.com/ssl-converter.html:
# The PKCS#12 or PFX format is a binary format for storing the server certificate,
# any intermediate certificates, and the private key in one encryptable file. PFX
# files usually have extensions such as .pfx and .p12. PFX files are typically used 
# on Windows machines to import and export certificates and private keys.

TMPPW=$$ # Some random password

PKCS12FILE=`mktemp`

if [[ $? != 0 ]]; then
  echo "Creation of temporary PKCS12 file failed -- exiting" >&2; exit 1
fi

TRANSITFILE=`mktemp`

if [[ $? != 0 ]]; then
  echo "Creation of temporary transit file failed -- exiting" >&2; exit 1
fi

cat "$KEY" "$LEAFCERT" > "$TRANSITFILE"

openssl pkcs12 -export -passout "pass:$TMPPW" -in "$TRANSITFILE" -name etl-web > "$PKCS12FILE"

/bin/rm "$TRANSITFILE"

# Print out result for fun! Bug in doc (I think): "-pass " arg does not work, need "-passin"

openssl pkcs12 -passin "pass:$TMPPW" -passout "pass:$TMPPW" -in "$PKCS12FILE" -info

# ----
# Import contents of PKCS12FILE into a Java keystore. WTF, Sun, what were you thinking?
# ----

if [[ -f "$TARGET_KEYSTORE" ]]; then
  /bin/rm "$TARGET_KEYSTORE"
fi

keytool -importkeystore \
   -deststorepass  "$TARGET_STOREPW" \
   -destkeypass    "$TARGET_STOREPW" \
   -destkeystore   "$TARGET_KEYSTORE" \
   -srckeystore    "$PKCS12FILE" \
   -srcstoretype  PKCS12 \
   -srcstorepass  "$TMPPW" \
   -alias foo-the-server

/bin/rm "$PKCS12FILE"

# ----
# Import the chain certificate. This works empirically, it is not at all clear from the doc whether this is correct
# ----

echo "Importing chain"

TT=-trustcacerts

keytool -import $TT -storepass "$TARGET_STOREPW" -file "$CHAINCERT" -keystore "$TARGET_KEYSTORE" -alias chain

# ----
# Print contents
# ----

echo "Listing result"

keytool -list -storepass "$TARGET_STOREPW" -keystore "$TARGET_KEYSTORE"
David Tonhofer
quelle
9

Zuerst auf p12 konvertieren:

openssl pkcs12 -export -in [filename-certificate] -inkey [filename-key] -name [host] -out [filename-new-PKCS-12.p12]

Erstellen Sie neue JKS ab Seite 12:

keytool -importkeystore -deststorepass [password] -destkeystore [filename-new-keystore.jks] -srckeystore [filename-new-PKCS-12.p12] -srcstoretype PKCS12
Michał Jurczuk
quelle
8

Ja, es ist in der Tat eine traurige Tatsache, dass Keytool keine Funktionalität zum Importieren eines privaten Schlüssels hat.

Am Ende habe ich mich für die hier beschriebene Lösung entschieden

Aleksandar Ivanisevic
quelle
6

In meinem Fall hatte ich eine PEM-Datei, die zwei Zertifikate und einen verschlüsselten privaten Schlüssel zur gegenseitigen SSL-Authentifizierung enthielt. Meine PEM-Datei sah also so aus:

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C8BF220FC76AA5F9
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Folgendes habe ich getan:

Teilen Sie die Datei in drei separate Dateien auf, sodass jede nur einen Eintrag enthält, beginnend mit "--- BEGIN .." und endend mit "--- END ..". Nehmen wir an, wir haben jetzt drei Dateien: cert1.pem cert2.pem und pkey.pem

Konvertieren Sie pkey.pem mit openssl und der folgenden Syntax in das DER-Format:

openssl pkcs8 -topk8 -nocrypt -in pkey.pem -inform PEM -out pkey.der -outform DER

Beachten Sie, dass, wenn der private Schlüssel verschlüsselt ist, Sie ein Passwort angeben müssen (erhalten Sie es vom Lieferanten der ursprünglichen PEM-Datei), um es in das DER-Format zu konvertieren. OpenSL fragt Sie nach dem Passwort wie folgt: "Geben Sie eine Pass-Phraze für pkey ein .pem: "Wenn die Konvertierung erfolgreich ist, erhalten Sie eine neue Datei mit dem Namen" pkey.der ".

Erstellen Sie einen neuen Java-Schlüsselspeicher und importieren Sie den privaten Schlüssel und die Zertifikate:

String keypass = "password";  // this is a new password, you need to come up with to protect your java key store file
String defaultalias = "importkey";
KeyStore ks = KeyStore.getInstance("JKS", "SUN");

// this section does not make much sense to me, 
// but I will leave it intact as this is how it was in the original example I found on internet:   
ks.load( null, keypass.toCharArray());
ks.store( new FileOutputStream ( "mykeystore"  ), keypass.toCharArray());
ks.load( new FileInputStream ( "mykeystore" ),    keypass.toCharArray());
// end of section..


// read the key file from disk and create a PrivateKey

FileInputStream fis = new FileInputStream("pkey.der");
DataInputStream dis = new DataInputStream(fis);
byte[] bytes = new byte[dis.available()];
dis.readFully(bytes);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

byte[] key = new byte[bais.available()];
KeyFactory kf = KeyFactory.getInstance("RSA");
bais.read(key, 0, bais.available());
bais.close();

PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
PrivateKey ff = kf.generatePrivate (keysp);


// read the certificates from the files and load them into the key store:

Collection  col_crt1 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert1.pem"));
Collection  col_crt2 = CertificateFactory.getInstance("X509").generateCertificates(new FileInputStream("cert2.pem"));

Certificate crt1 = (Certificate) col_crt1.iterator().next();
Certificate crt2 = (Certificate) col_crt2.iterator().next();
Certificate[] chain = new Certificate[] { crt1, crt2 };

String alias1 = ((X509Certificate) crt1).getSubjectX500Principal().getName();
String alias2 = ((X509Certificate) crt2).getSubjectX500Principal().getName();

ks.setCertificateEntry(alias1, crt1);
ks.setCertificateEntry(alias2, crt2);

// store the private key
ks.setKeyEntry(defaultalias, ff, keypass.toCharArray(), chain );

// save the key store to a file         
ks.store(new FileOutputStream ( "mykeystore" ),keypass.toCharArray());

(optional) Überprüfen Sie den Inhalt Ihres neuen Schlüsselspeichers:

keytool -list -keystore mykeystore -storepass password

Keystore-Typ: JKS Keystore-Anbieter: SUN

Ihr Keystore enthält 3 Einträge

cn = ..., ou = ..., o = .., 2. September 2014, trustedCertEntry, Zertifikatfingerabdruck (SHA1): 2C: B8: ...

importkey, 2. September 2014, PrivateKeyEntry, Zertifikatfingerabdruck (SHA1): 9C: B0: ...

cn = ..., o = ...., 2. September 2014, trustedCertEntry, Zertifikatfingerabdruck (SHA1): 83:63: ...

(optional) Testen Sie Ihre Zertifikate und Ihren privaten Schlüssel aus Ihrem neuen Schlüsselspeicher mit Ihrem SSL-Server: (Möglicherweise möchten Sie das Debuggen als VM-Option aktivieren: -Djavax.net.debug = all)

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        SSLSocketFactory factory = sclx.getSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket( "192.168.1.111", 443 );
        socket.startHandshake();

        //if no exceptions are thrown in the startHandshake method, then everything is fine..

Registrieren Sie abschließend Ihre Zertifikate bei HttpsURLConnection, wenn Sie diese verwenden möchten:

        char[] passw = "password".toCharArray();
        KeyStore ks = KeyStore.getInstance("JKS", "SUN");
        ks.load(new FileInputStream ( "mykeystore" ), passw );

        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
        kmf.init(ks, passw);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        TrustManager[] tm = tmf.getTrustManagers();

        SSLContext sclx = SSLContext.getInstance("TLS");
        sclx.init( kmf.getKeyManagers(), tm, null);

        HostnameVerifier hv = new HostnameVerifier()
        {
            public boolean verify(String urlHostName, SSLSession session)
            {
                if (!urlHostName.equalsIgnoreCase(session.getPeerHost()))
                {
                    System.out.println("Warning: URL host '" + urlHostName + "' is different to SSLSession host '" + session.getPeerHost() + "'.");
                }
                return true;
            }
        };

        HttpsURLConnection.setDefaultSSLSocketFactory( sclx.getSocketFactory() );
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
Interkot
quelle
Bruno erwähnte jedoch, dass diese Überprüfung des Hostnamens falsch ist: "Ihre Überprüfung des Hostnamens ist falsch. Session.getPeerHost () gibt nicht den Namen im Zertifikat zurück, sondern den Namen, mit dem Sie verbunden sind (dh den URL-Hostnamen hier) um wahr zu sein. Du kehrst sowieso immer wahr zurück. - Bruno ". Es hat zwar für mich funktioniert, aber ich würde mich freuen, wenn mir jemand zeigt, wie man einen guten Hostnamen-Verifizierer schreibt.
Interkot
1
Natürlich wird es für Sie "funktionieren", da es niemals einen Fehler erzeugt, selbst wenn es sollte. Belassen Sie die Standard-Hostnamenüberprüfung, die von verwendet wird, HttpsURLConnectionanstatt zu versuchen, Ihre eigenen zu schreiben. (Ein weiteres Problem mit Ihrem Beispiel ist, dass Sie den gleichen Schlüsselspeicher wie einen Schlüsselspeicher und einen Truststore verwenden, was nicht immer eine gute Idee ist ...)
Bruno
5

Basierend auf den obigen Antworten erfahren Sie hier, wie Sie einen brandneuen Keystore für Ihren Java-basierten Webserver aus einem unabhängig erstellten Comodo-Zertifikat und einem privaten Schlüssel mit keytool erstellen (JDK 1.6+ erforderlich).

  1. Geben Sie diesen Befehl ein und geben Sie an der Kennwortabfrage einen Pass ein. 'Server.crt' ist das Zertifikat Ihres Servers und 'server.key' ist der private Schlüssel, den Sie für die Ausgabe des CSR verwendet haben: openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name www.yourdomain.com -CAfile AddTrustExternalCARoot.crt -caname "AddTrust External CA Root"

  2. Verwenden Sie dann Keytool, um den p12-Keystore in einen jks-Keystore zu konvertieren: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

Importieren Sie dann die beiden anderen Root- / Intermediate-Zertifikate, die Sie von Comodo erhalten haben:

  1. Importieren Sie COMODORSAAddTrustCA.crt: keytool -import -trustcacerts -alias cert1 -file COMODORSAAddTrustCA.crt -keystore keystore.jks

  2. Importieren Sie COMODORSADomainValidationSecureServerCA.crt: keytool -import -trustcacerts -alias cert2 -file COMODORSADomainValidationSecureServerCA.crt -keystore keystore.jks

Fotios Basagiannis
quelle
5

Verwenden von Let's Encrypt-Zertifikaten

Angenommen, Sie haben Ihre Zertifikate und privaten Schlüssel mit Let's Encrypt erstellt in /etc/letsencrypt/live/you.com:

1. Erstellen Sie eine PKCS # 12- Datei

openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 \
        -name letsencrypt

Dies kombiniert Ihr SSL-Zertifikat fullchain.pemund Ihren privaten Schlüssel privkey.pemin einer einzigen Datei pkcs.p12.

Sie werden aufgefordert, ein Passwort für einzugeben pkcs.p12.

Die exportOption gibt an, dass eine PKCS # 12-Datei erstellt und nicht analysiert wird (aus dem Handbuch ).

2. Erstellen Sie den Java-Keystore

keytool -importkeystore -destkeystore keystore.jks -srckeystore pkcs.p12 \
        -srcstoretype PKCS12 -alias letsencrypt

Wenn keystore.jkses nicht vorhanden ist, wird es mit der pkcs.12oben erstellten Datei erstellt. Andernfalls importieren Sie pkcs.12in den vorhandenen Schlüsselspeicher.


Diese Anweisungen stammen aus diesem Blog-Beitrag .

Hier erfahren Sie mehr über die verschiedenen Arten von Dateien in /etc/letsencrypt/live/you.com/.

Matthias Braun
quelle
4

Mit diesen Schritten können Sie den Schlüssel in einen vorhandenen Schlüsselspeicher importieren. Die Anweisungen werden aus den Antworten in diesem Thread und anderen Websites kombiniert. Diese Anleitung hat bei mir funktioniert (der Java Keystore):

  1. Lauf

openssl pkcs12 -export -in yourserver.crt -inkey yourkey.key -out server.p12 -name somename -certfile yourca.crt -caname root

(Falls erforderlich, setzen Sie die Option -chain. Das Setzen ist für mich fehlgeschlagen.) Dies fragt nach dem Passwort - Sie müssen das richtige Passwort eingeben, sonst erhalten Sie einen Fehler (Überschriftenfehler oder Auffüllfehler usw.).

  1. Sie werden aufgefordert, ein neues Passwort einzugeben. Sie müssen hier ein Passwort eingeben. Geben Sie etwas anderes ein, als sich daran zu erinnern. (Nehmen wir an, Sie betreten Aragorn).
  2. Dadurch wird die Datei server.p12 im pkcs-Format erstellt.
  3. Um es nun in die *.jksDatei zu importieren, führen Sie Folgendes aus:
    keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore yourexistingjavakeystore.jks -deststoretype JKS -deststorepass existingjavastorepassword -destkeypass existingjavastorepassword
    den Dateilauf (Sehr wichtig - lassen Sie die Parameter deststorepass und destkeypass nicht aus.)
  4. Sie werden nach dem Kennwort für den src-Schlüsselspeicher gefragt. Geben Sie Aragorn ein und drücken Sie die Eingabetaste. Das Zertifikat und der Schlüssel werden jetzt in Ihren vorhandenen Java-Keystore importiert.
vanval
quelle
3

Frühere Antworten weisen richtig darauf hin, dass Sie dies nur mit den Standard-JDK-Tools tun können, indem Sie zuerst die JKS-Datei in das PKCS # 12-Format konvertieren. Wenn Sie interessiert sind, habe ich ein kompaktes Dienstprogramm zum Importieren von OpenSSL-abgeleiteten Schlüsseln in einen JKS-formatierten Schlüsselspeicher zusammengestellt, ohne den Schlüsselspeicher zuerst in PKCS # 12 konvertieren zu müssen: http://commandlinefanatic.com/cgi-bin/showarticle. cgi? article = art049

Sie würden das verknüpfte Dienstprogramm wie folgt verwenden:

$ openssl req -x509 -newkey rsa:2048 -keyout localhost.key -out localhost.csr -subj "/CN=localhost"

(CSR unterschreiben, localhost.cer zurückholen)

$ openssl rsa -in localhost.key -out localhost.rsa
Enter pass phrase for localhost.key:
writing RSA key
$ java -classpath . KeyImport -keyFile localhost.rsa -alias localhost -certificateFile localhost.cer -keystore localhost.jks -keystorePassword changeit -keystoreType JKS -keyPassword changeit
Joshua Davies
quelle
Nur eine Verknüpfung mit Ihrer eigenen Bibliothek (oder Ihrem eigenen Dienstprogramm) ist keine gute Antwort. Wenn Sie darauf verlinken, erklären, warum das Problem gelöst wird, Code bereitstellen, der es verwendet, und dies ablehnen, erhalten Sie eine bessere Antwort. Siehe: Wie kann ich auf Community-freundliche Weise eine Verknüpfung zu einer externen Ressource herstellen?
Mogsdad
Ich bin mir nicht sicher, was Sie unter "Haftungsausschluss" verstehen, aber ich habe ein Beispiel hinzugefügt.
Joshua Davies
Toll! Das ist ein eingemachter Kommentar, daher galt ein Teil nicht - Haftungsausschluss bedeutet, dass Sie Ihre Zugehörigkeit zu dem verknüpften Produkt oder der verknüpften Dienstleistung melden, die Sie mit "Ich habe ..." zusammengestellt haben
Mogsdad
3

Wenn Sie eine PEM-Datei (z. B. server.pem) haben, die Folgendes enthält:

  • das vertrauenswürdige Zertifikat
  • der private Schlüssel

Anschließend können Sie das Zertifikat und den Schlüssel wie folgt in einen JKS-Keystore importieren:

1 ) Kopieren Sie den privaten Schlüssel aus der PEM-Datei in eine ASCII-Datei (zserver.key )

2 ) Kopieren Sie das Zertifikat aus der PEM-Datei in eine ASCII-Datei (zserver.crt )

3 ) Exportieren Sie das Zertifikat und den Schlüssel in eine PKCS12-Datei:

$ openssl pkcs12 -export -in server.crt -inkey server.key \
                 -out server.p12 -name [some-alias] -CAfile server.pem -caname root
  • Die PEM-Datei kann als Argument für die -CAfileOption verwendet werden .
  • Sie werden aufgefordert, ein 'Export'-Passwort einzugeben.
  • Wenn Sie dies in git bash tun, fügen Sie winptyes am Anfang des Befehls hinzu, damit das Exportkennwort eingegeben werden kann.

4 ) Konvertieren Sie die PKCS12-Datei in einen JKS-Keystore:

$ keytool -importkeystore -deststorepass changeit -destkeypass changeit \
          -destkeystore keystore.jks  -srckeystore server.p12 -srcstoretype PKCS12 \
          -srcstorepass changeit
  • Das srcstorepassPasswort sollte mit dem Exportpasswort aus Schritt 3) übereinstimmen.
Joman68
quelle
3

Was ich erreichen wollte, war die Verwendung des bereits bereitgestellten privaten Schlüssels und Zertifikats zum Signieren einer Nachricht, die an einen Ort ging, an dem sichergestellt werden musste, dass die Nachricht von mir kam (privates Schlüsselzeichen, während öffentliche Schlüssel verschlüsseln).

Also, wenn Sie bereits eine .key-Datei und eine .crt-Datei haben?

Versuche dies:

Schritt 1: Konvertieren Sie den Schlüssel und das Zertifikat in die P12-Datei

openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -name alias -out yourconvertedfile.p12

Schritt 2: Importieren Sie den Schlüssel und erstellen Sie eine .jsk-Datei mit einem einzigen Befehl

keytool -importkeystore -deststorepass changeit -destkeystore keystore.jks -srckeystore umeme.p12 -srcstoretype PKCS12

Schritt 3: In Ihrem Java:

char[] keyPassword = "changeit".toCharArray();

KeyStore keyStore = KeyStore.getInstance("JKS");
InputStream keyStoreData = new FileInputStream("keystore.jks");

keyStore.load(keyStoreData, keyPassword);
KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(keyPassword);
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry("alias", entryPassword);

System.out.println(privateKeyEntry.toString());

Wenn Sie mit diesem Schlüssel eine Zeichenfolge signieren müssen, gehen Sie wie folgt vor:

Schritt 1: Konvertieren Sie den zu verschlüsselnden Text

byte[] data = "test".getBytes("UTF8");

Schritt 2: Holen Sie sich den Base64-codierten privaten Schlüssel

keyStore.load(keyStoreData, keyPassword);

//get cert, pubkey and private key from the store by alias
Certificate cert = keyStore.getCertificate("localhost");
PublicKey publicKey = cert.getPublicKey();
KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);

//sign with this alg
Signature sig = Signature.getInstance("SHA1WithRSA");
sig.initSign(keyPair.getPrivate());
sig.update(data);
byte[] signatureBytes = sig.sign();
System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));

sig.initVerify(keyPair.getPublic());
sig.update(data);

System.out.println(sig.verify(signatureBytes));

Verweise:

  1. Wie importiere ich ein vorhandenes x509-Zertifikat und einen privaten Schlüssel in den Java-Keystore, um sie in SSL zu verwenden?
  2. http://tutorials.jenkov.com/java-cryptography/keystore.html
  3. http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm
  4. So signieren Sie eine Zeichenfolge mit einem privaten Schlüssel

Endgültiges Programm

public static void main(String[] args) throws Exception {

    byte[] data = "test".getBytes("UTF8");

    // load keystore
    char[] keyPassword = "changeit".toCharArray();

    KeyStore keyStore = KeyStore.getInstance("JKS");
    //System.getProperty("user.dir") + "" < for a file in particular path 
    InputStream keyStoreData = new FileInputStream("keystore.jks");
    keyStore.load(keyStoreData, keyPassword);

    Key key = keyStore.getKey("localhost", keyPassword);

    Certificate cert = keyStore.getCertificate("localhost");

    PublicKey publicKey = cert.getPublicKey();

    KeyPair keyPair = new KeyPair(publicKey, (PrivateKey) key);

    Signature sig = Signature.getInstance("SHA1WithRSA");

    sig.initSign(keyPair.getPrivate());
    sig.update(data);
    byte[] signatureBytes = sig.sign();
    System.out.println("Signature:" + Base64.getEncoder().encodeToString(signatureBytes));

    sig.initVerify(keyPair.getPublic());
    sig.update(data);

    System.out.println(sig.verify(signatureBytes));
}
Mwa Joe
quelle
1

Erstellen Sie einfach einen PKCS12-Keystore, Java kann ihn jetzt direkt verwenden. Wenn Sie einen Keystore im Java-Stil auflisten, weist Sie das Keytool selbst darauf hin, dass PKCS12 jetzt das bevorzugte Format ist.

openssl pkcs12 -export -in server.crt -inkey server.key \
               -out server.p12 -name [some-alias] \
               -CAfile ca.crt -caname root -chain

Sie sollten alle drei Dateien (server.crt, server.key, ca.crt) von Ihrem Zertifikatanbieter erhalten haben. Ich bin nicht sicher, was "-caname root" eigentlich bedeutet, aber es scheint so spezifiziert werden zu müssen.

Stellen Sie im Java-Code sicher, dass Sie den richtigen Keystore-Typ angeben.

KeyStore.getInstance("PKCS12")

Auf diese Weise funktioniert mein von comodo.com ausgestelltes SSL-Zertifikat in NanoHTTPD einwandfrei.

Stefan Reich
quelle