Comment importer un certificat X.509 existant et une clé privée dans le magasin de clés Java à utiliser dans SSL?

228

J'ai ceci dans une configuration ActiveMQ:

<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 cert X.509 et un fichier clé.

Comment importer ces deux afin de les utiliser dans les connecteurs SSL et SSL + stomp? Tous les exemples que j'ai pu 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 ne fait qu'importer le certificat et non le fichier clé et se traduit par

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 certificat et la clé, mais j'ai obtenu le même résultat.

Comment importer la clé?

Aleksandar Ivanisevic
la source
1
Vous devez en fait écrire un peu de code pour ce faire, et les détails dépendent du format de la clé privée que vous essayez d'importer. Quel format est votre clé? Pouvez-vous expliquer les outils que vous avez utilisés pour générer la clé et le certificat dont vous disposez?
erickson
Pour SSL bidirectionnel (certificat client et serveur) avec Spring Boot, voir stackoverflow.com/a/59317888/548473
Grigory Kislin

Réponses:

73

Croyez-le ou non, keytool ne fournit pas de fonctionnalités de base telles que l'importation de clés privées dans le magasin de clés. Vous pouvez essayer cette solution de contournement en fusionnant le fichier PKSC12 avec la clé privée dans un magasin de clés.

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

Matej
la source
11
Selon l'outil de réponse de CoverosGene, Keytool le prend en charge depuis Java 6. C'est le lien qu'il a fourni
Houtman
Pour ce que ça vaut, pour tout le bruit à ce sujet, le meilleur lien est le lien de «contournement» de @ Matej vers ce message de 2008: cunning.sharp.fm/2008/06/importing_private_keys_into_a.html
cloudsurfin
2
J'ai suivi la réponse fournie par CoverosGene et cela a fonctionné.
Robert3452
1
KeyMan ne me semble pas très convivial.
Miscreant
15
Lien cassé. Veuillez inclure les détails de la solution directement dans la réponse :-(
lilalinux
536

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 le certificat et la clé x.509 en un 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 mettre un mot de passe sur le fichier pkcs12 - sinon vous obtiendrez une exception de pointeur nul lorsque vous essayez de l'importer. (Au cas où quelqu'un d'autre aurait eu ce mal de tête). ( Merci jocull! )

Remarque 2: vous souhaiterez peut-être ajouter l' -chainoption de conservation de la chaîne de certificats complète. ( Merci Mafuba )

Deuxième étape: convertir le fichier pkcs12 en un fichier 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

FACULTATIF Étape zéro: créer un 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

À votre santé!

reto
la source
12
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. (Au cas où quelqu'un d'autre aurait eu ce mal de tête)
jocull
9
Dans mon cas, à la première étape, l'option -CAfile ca.crt -caname rootn'a pas correctement émis les certificats CA. Au lieu de cela, j'ai utilisé-certfile concatenedCAFiles.pem
dcernahoschi
11
N'oubliez pas d'utiliser l' -chainargument avec openssl pour inclure la chaîne de certificats complète dans votre fichier pfx / p12 si vous le souhaitez dans votre magasin de clés.
Mafuba
3
Dans un environnement Windows, pvk2pfx(un outil VS standard disponible dans l' cmdinvite VS ) crachera un - .pfxéquivalent à un .p12. Les conseils de @ jocull sont toujours d'actualité; mettre un mot de passe dessus. Pas opensslnécessaire.
Ben Mosher
9
Pour Tomcat en particulier, il est impératif que le magasin de clés et les mots de passe clés soient identiques. Lorsque vous importez une .p12clé, le mot de passe du .p12.Tomcat d' origine échouera java.security.UnrecoverableKeyException: Cannot recover key. En d'autres termes: si vous devez exécuter -deststorepass changeit -srcstorepass some-passwordavec des mots de passe différents , vous devez inclure -destkeypass changeit(avec le même mot de passe que -deststorepass)
Slav
127

Keytool dans Java 6 a cette capacité: Importation de clés privées dans un magasin de clés Java à l'aide de keytool

Voici les détails de base de ce post.

  1. Convertissez le certificat existant en PKCS12 à l'aide d'OpenSSL. Un mot de passe est requis lorsque demandé ou la 2è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 de clés 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]
CoverosGene
la source
4
La réponse de @reto contient le contenu de ce lien.
Mafuba
4
Comme indiqué par @Mafuba, vous devez toujours créer un magasin de clés pkcs12 distinct avec un outil non java comme openssl - puis il peut être importé dans un magasin jks par keytool comme indiqué dans la réponse de reto.
Mister_Tom
Une chose qui en fait une bonne réponse est le fait que les certificats d'entrée sont clairement spécifiés entre parenthèses.
Mr.Budris
FWIW, la sortie de l' étape 1 devrait déjà être utilisable comme Java keystore (si l' étape 2 ne peut pas être nécessaire - à moins que vous ne devez importer les cert + clé dans une existante keystore) - comme déjà mentionné dans une réponse précédente par @ jaco0646
Janaka Bandara
9

Et encore un:

#!/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
la source
9

Convertissez d'abord en p12:

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

Créez un nouveau JKS à partir de p12:

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

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

Aleksandar Ivanisevic
la source
6

Dans mon cas, j'avais un fichier pem qui contenait deux certificats et une clé privée cryptée à utiliser dans 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 ne contienne qu'une seule entrée, commençant par "--- BEGIN .." et se 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 cryptée, vous devez fournir un mot de passe (à obtenir auprès du fournisseur du fichier pem d'origine) pour la convertir au format DER, openssl vous demandera le mot de passe comme ceci: "entrez une passe phraze pour pkey .pem: "Si la conversion réussit, vous obtiendrez un nouveau fichier appelé" pkey.der "

Créez un nouveau magasin de clés java et importez 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());

(facultatif) Vérifiez le contenu de votre nouveau magasin de clés:

keytool -list -keystore mykeystore -storepass password

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

Votre keystore contient 3 entrées

cn = ..., ou = ..., o = .., 2 sept. 2014, trustedCertEntry, Certificat d'empreinte digitale (SHA1): 2C: B8: ...

importkey, 2 sept. 2014, PrivateKeyEntry, Certificat d'empreinte digitale (SHA1): 9C: B0: ...

cn = ..., o = ...., 2 sept. 2014, trustedCertEntry, Certificat d'empreinte digitale (SHA1): 83:63: ...

(facultatif) Testez vos certificats et votre clé privée à partir de votre nouveau magasin de clés par rapport à 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 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);
Interkot
la source
Cependant, Bruno a mentionné que ce vérificateur de nom d’hôte est erroné: "Votre vérificateur de nom d’hôte est incorrect, session.getPeerHost () ne renvoie pas le nom dans le certificat, mais le nom avec lequel vous vous êtes connecté (c.-à-d. L'urlHostName ici), donc pour être vrai. Tu reviens toujours vrai de toute façon. - Bruno ". Cela a fonctionné pour moi, mais j'apprécierais que quelqu'un me montre comment écrire un bon vérificateur de nom d'hôte.
Interkot
1
Bien sûr, cela "fonctionnera" pour vous, car il ne produira jamais d'erreur, même quand il le devrait. Laissez le vérificateur de nom d'hôte par défaut utilisé par HttpsURLConnectionau lieu d'essayer d'écrire le vôtre. (Un autre problème avec votre exemple est que vous utilisez le même keystore qu'un keystore et un truststore, ce qui n'est pas toujours une bonne idée ...)
Bruno
6

Utilisation des certificats Let's Encrypt

En supposant que vous avez créé vos certificats et clés privées avec Let's Encrypt dans /etc/letsencrypt/live/you.com:

1. Créez un fichier PKCS # 12

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

Celui - ci combine votre certificat SSL fullchain.pemet votre clé privée privkey.pemdans un seul fichier, pkcs.p12.

Vous serez invité à entrer un mot de passe pour pkcs.p12.

L' exportoption spécifie qu'un fichier PKCS # 12 sera créé plutôt qu'analysé (à partir du manuel ).

2. Créez le magasin de clés Java

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

S'il keystore.jksn'existe pas, il sera créé contenant le pkcs.12fichier créé ci-dessus. Sinon, vous importerez pkcs.12dans le magasin de clés existant.


Ces instructions sont dérivées de cet article de blog .

Voici plus sur les différents types de fichiers dans /etc/letsencrypt/live/you.com/.

Matthias Braun
la source
5

Sur la base des réponses ci-dessus, voici comment créer un tout nouveau magasin de clés pour votre serveur Web basé sur java, à partir d'un certificat Comodo créé indépendamment et d'une clé privée à l'aide de keytool (nécessite JDK 1.6+)

  1. Exécutez cette commande et à l'invite de mot de passe, saisissez somepass - 'server.crt' est le certificat 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 magasin de clés p12 en magasin de clés jks: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

Importez ensuite les deux autres certificats racine / intermédiaires que vous avez reçus de Comodo:

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

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

Fotios Basagiannis
la source
4

Vous pouvez utiliser ces étapes pour importer la clé dans un magasin de clés existant. Les instructions sont combinées à partir des réponses de ce fil et d'autres sites. Ces instructions ont fonctionné pour moi (le 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, mettez l'option -chain. Mettre 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 autre chose que vous en souvenez. (Supposons que vous entrez dans Aragorn).
  2. Cela créera le fichier server.p12 au format pkcs.
  3. Maintenant, pour l'importer dans le *.jksfichier exécuté:
    keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore yourexistingjavakeystore.jks -deststoretype JKS -deststorepass existingjavastorepassword -destkeypass existingjavastorepassword
    (Très important - ne laissez pas de côté les paramètres deststorepass et destkeypass.)
  4. Il vous demandera le mot de passe du magasin de clés src. Entrez Aragorn et appuyez sur Entrée. Le certificat et la clé sont désormais importés dans votre magasin de clés Java existant.
vanval
la source
3

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 au 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 magasin de clés au format JKS sans avoir à convertir d'abord le magasin 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"

(signez le CSR, récupérez 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
Joshua Davies
la source
Un simple lien vers votre propre bibliothèque (ou utilitaire) n'est pas une bonne réponse. Un lien vers celui-ci, expliquant pourquoi il résout le problème, fournissant du code l'utilisant pour le faire et en refusant une meilleure réponse. Voir: Comment puis-je me connecter à une ressource externe de manière conviviale pour la communauté?
Mogsdad
Je ne sais pas trop ce que vous entendez par "renoncer", mais j'ai ajouté un exemple.
Joshua Davies
Génial! C'est un commentaire en conserve, donc une partie ne s'applique pas - décliner signifie signaler votre affiliation avec le produit ou service lié, ce que vous avez fait avec "J'ai mis en place ..."
Mogsdad
3

Si vous avez un fichier PEM (par exemple server.pem) contenant:

  • le certificat de confiance
  • la clé privée

vous pouvez ensuite importer le certificat et la clé dans un fichier de clés JKS comme celui-ci:

1 ) Copiez la clé privée du fichier PEM dans un fichier ascii (par exemple server.key)

2 ) Copiez le certificat du fichier PEM dans un fichier ascii (par exemple server.crt)

3 ) Exportez le certificat et la clé dans un fichier PKCS12:

$ openssl pkcs12 -export -in server.crt -inkey server.key \
                 -out server.p12 -name [some-alias] -CAfile server.pem -caname root
  • le fichier PEM peut être utilisé comme argument de l' -CAfileoption .
  • vous êtes invité à entrer un mot de passe «d'exportation».
  • si vous faites cela dans git bash, ajoutez winptyau début de la commande afin que le mot de passe d'exportation puisse être entré.

4 ) Convertissez le fichier PKCS12 en un fichier de clés JKS:

$ keytool -importkeystore -deststorepass changeit -destkeypass changeit \
          -destkeystore keystore.jks  -srckeystore server.p12 -srcstoretype PKCS12 \
          -srcstorepass changeit
  • le srcstorepassmot de passe doit correspondre au mot de passe d'exportation de l'étape 3)
Joman68
la source
3

Ce que j'essayais de réaliser était d'utiliser la clé privée et le certificat déjà fournis pour signer un message qui allait quelque part et qui devait s'assurer que le message venait de moi (les clés privées signent pendant que les clés publiques cryptent).

Donc, si vous avez déjà un fichier .key et un fichier .crt?

Essaye ça:

Étape 1: convertir la clé et le certificat en fichier .p12

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

Étape 2: importez la clé et créez un fichier .jsk avec une seule commande

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

Étape 3: Dans votre 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());

Si vous devez signer une chaîne à l'aide de cette clé, procédez comme suit:

Étape 1: convertir le texte que vous souhaitez crypter

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

Étape 2: obtenir la clé privée encodée en base64

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

Références:

  1. Comment importer un certificat x509 existant et une clé privée dans le magasin de clés Java à utiliser dans SSL?
  2. http://tutorials.jenkov.com/java-cryptography/keystore.html
  3. http://www.java2s.com/Code/Java/Security/RetrievingaKeyPairfromaKeyStore.htm
  4. Comment signer une chaîne avec une clé privée

Programme final

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
la source
1

Créez simplement un magasin de clés PKCS12, Java peut l'utiliser directement maintenant. En fait, si vous répertoriez un fichier de clés de style Java, keytool lui-même vous avertit que PKCS12 est désormais le format préféré.

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

Vous devez avoir reçu les trois fichiers (server.crt, server.key, ca.crt) de votre fournisseur de certificats. Je ne suis pas sûr de ce que signifie réellement "-caname root", mais cela semble devoir être spécifié de cette façon.

Dans le code Java, assurez-vous de spécifier le bon type de fichier de clés.

KeyStore.getInstance("PKCS12")

J'ai obtenu mon certificat SSL émis par comodo.com qui fonctionne bien dans NanoHTTPD de cette façon.

Stefan Reich
la source