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

J’ai ceci dans activemq config

   

J’ai une paire de cert x509 et un fichier de clé

Comment puis-je importer ces deux éléments à utiliser dans les connecteurs ssl et ssl + stomp? Tous les exemples que je pourrais google génèrent toujours 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 uniquement le certificate et non le fichier de clé et entraîne

2009-05-25 13:16:24,270 [localhost:61612] ERROR TransportConnector - Could not accept connection : No available certificatee 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 eu le même résultat

Comment importer la clé?

Croyez-le ou non, keytool ne fournit pas de fonctionnalités aussi simples que l’importation d’une clé privée dans le fichier de clés. Vous pouvez essayer cette solution en fusionnant le fichier PKSC12 avec la clé privée en un fichier de clés.

Ou utilisez simplement KeyMan d’IBM, plus convivial, pour la gestion des fichiers de clés au lieu de keytool.exe.

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

Première étape: Convertir x509 Cert et Key en fichier pkcs12

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

Remarque: Assurez-vous de placer un mot de passe sur le fichier p12. Sinon, vous obtiendrez une exception de référence null lorsque vous essayez de l’importer. (Au cas où quelqu’un d’autre aurait ce mal de tête). ( Merci jocull! )

Remarque 2: Vous souhaiterez peut-être append l’option -chain pour conserver la chaîne de certificates complète. ( Merci Mafuba )

Etape 2: Convertissez le fichier pkcs12 en magasin de clés java

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

Fini

OPTIONAL Step Zero, créer un certificate 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 

À votre santé!

Keytool dans Java 6 a cette capacité: Importer des clés privées dans un keystore Java à l’aide de keytool

Voici les détails de base de cet article.

  1. Convertir le cert existant en PKCS12 en utilisant OpenSSL. Un mot de passe est requirejs lorsque demandé ou la 2ème étape se plaindra.

     openssl pkcs12 -export -in [my_certificatee.crt] -inkey [my_key.key] -out [keystore.p12] -name [new_alias] -CAfile [my_ca_bundle.crt] -caname root 
  2. Convertissez le PKCS12 en fichier Keystore Java.

     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] 

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 # certificateion outfit, also in PEM format ("-----BEGIN CERTIFICATE-----") # 3) $CHAINCERT : Intermediate certificatee 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): # #  # # 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 certificatee, # any intermediate certificatees, 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 certificatees 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 certificatee. 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" 

Oui, c’est en effet un sortingste fait que keytool n’ait aucune fonctionnalité pour importer une clé privée.

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

Dans mon cas, j’avais un fichier pem contenant deux certificates et une clé privée chiffrée à utiliser pour l’authentification SSL mutuelle. 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:

Divisez le fichier en trois fichiers distincts, de sorte que chacun contienne une seule entrée, en commençant par “— BEGIN ..” et en terminant par “— END ..”. 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 chiffrée, vous devez fournir un mot de passe (obtenez-le du fournisseur du fichier pem d’origine) pour le convertir au format DER, openssl vous demandera le mot de passe comme suit: .pem: “Si la conversion est réussie, vous obtiendrez un nouveau fichier appelé” pkey.der ”

Créez un magasin de clés java et importez la clé privée et les certificates:

 Ssortingng keypass = "password"; // this is a new password, you need to come up with to protect your java key store file Ssortingng 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 certificatees 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 }; Ssortingng alias1 = ((X509Certificate) crt1).getSubjectX500Principal().getName(); Ssortingng 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()); 

(facultatif) Vérifiez le contenu de votre nouvelle clé de stockage:

keytool -list -keystore mykeystore -storepass password

Type de magasin de clés: Fournisseur de clés JKS: SUN

Votre keystore contient 3 entrées

cn = …, ou = …, o = .., 2 septembre 2014, trustedCertEntry, empreinte de certificate (SHA1): 2C: B8: …

importkey, 2 sep 2014, PrivateKeyEntry, empreinte de certificate (SHA1): 9C: B0: …

cn = …, o = …., 2 septembre 2014, trustedCertEntry, empreinte de certificate (SHA1): 83:63: …

(facultatif) Testez vos certificates et votre clé privée à partir de votre nouvelle clé de stockage sur votre serveur SSL: (Vous pouvez activer le débogage en tant qu’option de machine virtuelle: -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 certificates 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(Ssortingng 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); 

Sur la base des réponses ci-dessus, voici comment créer un nouveau fichier de clés pour votre serveur Web Java, à partir d’un certificate Comodo et d’une clé privée créés de manière indépendante à l’aide de keytool (nécessite JDK 1.6+).

  1. Emettez cette commande et à l’invite du mot de passe, entrez somepass – ‘server.crt’ est le certificate de votre serveur et ‘server.key’ est la clé privée que vous avez utilisée pour émettre le 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. Utilisez ensuite keytool pour convertir le keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass : keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

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

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

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

Première conversion en p12:

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

Créez de nouveaux JKS à partir de p12:

 keytool -importkeystore -deststorepass [password] -destkeystore [filename-new-keystore.jks] -srckeystore [filename-new-PKCS-12.p12] -srcstoretype PKCS12 

Voici les étapes que j’ai suivies pour importer la clé dans un magasin de clés existant: des instructions combinées à partir des réponses fournies ici et à d’autres endroits pour obtenir ces étapes qui ont fonctionné pour mon magasin de clés java:

  1. Courir

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

(Si nécessaire, placez l’option -chain. Cela a échoué pour moi). Cela vous demandera le mot de passe – vous devez donner le mot de passe correct sinon vous obtiendrez une erreur (erreur de cap ou erreur de remplissage, etc.).

  1. Il vous demandera d’entrer un nouveau mot de passe – vous devez entrer un mot de passe ici – entrez tout, mais ne vous en souvenez pas. (Supposons que vous entrez Aragorn).
  2. Cela créera le fichier server.p12 au format pkcs.
  3. Maintenant, importez-le dans le fichier *.jks exécuté:

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore yourexistingjavakeystore.jks -deststoretype JKS

(Très important – ne laissez pas de côté les parameters deststorepass et destkeypass.)
5. Il vous demandera le mot de passe du magasin de clés src. Entrez Aragorn et appuyez sur Entrée. Le certificate et la clé sont maintenant importés dans votre magasin de clés java existant.

Les réponses précédentes soulignent correctement que vous ne pouvez le faire qu’avec les outils JDK standard en convertissant d’abord le fichier JKS au format PKCS # 12. Si cela vous intéresse, j’ai créé un utilitaire compact pour importer des clés OpenSSL dans un fichier de clés au format JKS sans avoir à convertir le fichier de clés en PKCS # 12: 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 le CSR, retourne 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 -certificateeFile localhost.cer -keystore localhost.jks -keystorePassword changeit -keystoreType JKS -keyPassword changeit