Comment importer un certificat x509 existant et une clé privée dans Java keystore à utiliser dans SSL?

j'ai cela en activemq config

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

j'ai une paire de x509 cert et un fichier clé

Comment puis-je importer ces deux pièces pour les utiliser dans les connecteurs ssl et ssl+stomp? Tous les exemples que je pouvais google toujours générer la clé eux-mêmes, mais j'ai déjà une clé.

j'ai essayé

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

mais cela importe seulement le certificat et non le fichier clé et les résultats en

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.

j'ai essayé de concaténer le cert et la clé mais j'ai obtenu le même résultat

Comment puis-je importer la clé?

183
demandé sur jww 2009-05-25 15:34:01

10 réponses

croyez ou non, keytool ne fournit pas une telle fonctionnalité de base comme l'importation de clé privée à keystore. Vous pouvez essayer ce solution de contournement avec le fichier pksc12 de fusion avec la clé privée d'un keystore.

ou tout simplement utiliser plus convivial KeyMan D'IBM pour la manipulation de keystore au lieu de keytool.EXE.

63
répondu Matej 2012-10-24 10:58:55

j'ai utilisé les deux étapes suivantes que j'ai trouvées dans les commentaires/postes liés dans les autres réponses:

première étape: conversion du certificat x509 à un fichier pkcs12

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

Note: assurez - vous de mettre un mot de passe sur le fichier p12-sinon vous obtiendrez une exception de référence nulle lorsque vous essayez de l'importer. (Dans le cas où quelqu'un d'autre avait ce mal de tête). ( Merci jocull! )

Note 2: vous pourriez vouloir ajouter l'option -chain pour préserver la chaîne de certificat complète. ( Grâce Mafuba )

deuxième étape: conversion du fichier pkcs12 en un keystore java

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

fini

étape facultative Zéro, créer le certificat auto-signé

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

santé!

454
répondu reto 2015-06-17 14:04:51

Keytool en Java 6 a cette capacité: importation de clés privées dans un clavier Java en utilisant

Voici les détails de base de ce poste.

  1. convertissez le certificat existant en PKCS12 en utilisant OpenSSL. Un mot de passe est nécessaire lorsque demandé ou la deuxième étape se plaindra.

    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. convertissez le PKCS12 en un fichier Java Keystore.

    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]
    
109
répondu CoverosGene 2018-03-06 09:55:08

et un de plus:

#!/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"
9
répondu David Tonhofer 2015-07-27 23:08:26

Oui, c'est en effet un triste fait que keytool n'a pas de fonctionnalité pour importer une clé privée.

pour mémoire, à la fin je suis allé avec la solution décrite ici

8
répondu Aleksandar Ivanisevic 2016-09-10 03:26:17

dans mon cas, j'avais un fichier pem qui contenait deux certificats et une clé privée cryptée à utiliser dans l'authentification mutuelle SSL. Donc mon fichier pem ressemblait à ceci:

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

voici ce que j'ai fait:

divise le fichier en trois fichiers séparés, de sorte que chacun ne contient qu'une entrée, en commençant par " - - - commence.."et se terminant par "---FIN.." ligne. Supposons que nous avons maintenant trois fichiers: cert1.pem cert2.pem et pkey.pem

Convertissez pkey.pem au format DER en utilisant openssl et la syntaxe suivante:

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

notez que si la clé privée est cryptée vous devez fournir un mot de passe( obtenez-le du fournisseur du fichier pem original ) pour convertir au format DER, openssl vous demandera le mot de passe comme ceci: "entrez un Phraze pass pour pkey.pem: " Si la conversion est réussie, vous obtiendrez un nouveau fichier appelé "pkey.der "

Créer un nouveau magasin de clés java et importer la clé privée et les certificats:

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

(optionnel) vérifiez le contenu de votre nouveau magasin de clés:

keytool -list -keystore mykeystore -storepass password

type de magasin de clés: JKS Keystore fournisseur de: SUN

votre keystore contient 3 entrées""

cn=...,UO.=..,o=.., 2 sept. 2014, attestation de surveillance de la confiance (trustedcerteny) empreinte digitale (SHA1): 2C: B8:...

importkey, Sep 2, 2014, PrivateKeyEntry, empreinte digitale de certificat (SHA1): 9C: B0:...

cn=...,o=...., 2 sept. 2014, empreinte digitale du certificat trustedCertEntry (SHA1): 83:63: ...

(optionnel) Testez vos certificats et vos clés privées depuis votre nouveau magasin de clés contre votre serveur SSL: ( Vous pouvez activer le débogage en option VM: - 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..

Enfin, enregistrez vos certificats Avec HttpsURLConnection si vous prévoyez de l'utiliser:

        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);
6
répondu Interkot 2016-05-18 13:17:26

première conversion en p12:

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

créer de nouveaux JKS à partir de p12:

keytool -importkeystore -deststorepass [password] -destkeystore [filename-new-keystore.jks] -srckeystore [filename-new-PKCS-12.p12] -srcstoretype PKCS12
5
répondu Michał Jurczuk 2017-06-01 08:49:59

basé sur les réponses ci-dessus, voici comment créer un tout nouveau keystore pour votre serveur web basé sur java, à partir d'un certificat Comodo créé indépendamment et clé privée en utilisant keytool (nécessite JDK 1.6+)

  1. lancez cette commande et à l'invite de mot de passe entrez somepass - 'server.crt ' est le serveur cert et 'de votre serveur.la clé ' est la clé privée que vous avez utilisée pour l'émission du CSR: 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. alors utilisez keytool pour convertir le keystore p12 en un keystore jks: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

ensuite, importez les deux autres certs racine / intermédiaire que vous avez reçus de Comodo:

  1. Import Comodorsaaddustca.crt: keytool -import -trustcacerts -alias cert1 -file COMODORSAAddTrustCA.crt -keystore keystore.jks

  2. Import COMODORSADomainValidationSecureServerca.crt: keytool -import -trustcacerts -alias cert2 -file COMODORSADomainValidationSecureServerCA.crt -keystore keystore.jks

5
répondu Alex Fotios 2017-12-21 17:32:13

Voici les étapes que j'ai suivies pour importer la clé d'un keystore existant - instructions combinées à partir des réponses ici et d'autres endroits pour obtenir ces étapes qui ont fonctionné pour mon java keystore:

  1. Exécuter

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

(si nécessaire, mettre l'option-chain. La mise qui a échoué pour moi). Cela demandera le mot de passe - vous devez donner le mot de passe correct sinon vous obtiendrez une erreur (rubrique erreur ou erreur de remplissage etc).

  1. il vous demandera d'entrer un nouveau mot de passe - vous devez entrer un mot de passe ici - entrer n'importe quoi sauf Se souvenir. (Supposons que vous entrez Aragorn).
  2. cela créera le serveur.fichier P12 au format pkcs.
  3. Maintenant l'importer dans le *.jks de l'exécution du fichier:

keytool-importkeystore-srckeystore server.P12-srcstoretype PKCS12 - destkeystore yourexistingjavakeystore.jks-deststoretype JKS-deststorepass existingjavastorepassword-destkeypass existingjavastorepassword

(très important - n'oubliez pas les paramètres deststorepass et destkeypass.)

5. Il vous demandera le mot de passe src key store. Entre Aragorn et frappe entrée. Le certificat et la clé sont maintenant importés dans votre Java keystore existant.

4
répondu vanval 2017-07-13 14:27:25

les réponses précédentes indiquent correctement que vous ne pouvez le faire qu'avec les outils JDK standard en convertissant d'abord le fichier JKS en format PKCS #12. Si vous êtes intéressé, j'ai mis en place un utilitaire compact pour importer des clés dérivées D'OpenSSL dans un keystore formaté par JKS sans avoir à convertir le keystore en PKCS #12 en premier: http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art049

vous utiliseriez l'utilitaire lié comme ceci:

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

(signe de la RSE, de revenir localhost.cer)

$ 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
3
répondu Joshua Davies 2016-03-03 18:47:22