jms keytool - Come importare un certificato x509 esistente e una chiave privata nel keystore Java da utilizzare in SSL?




add jks (9)

In base alle risposte sopra, ecco come creare un nuovo keystore per il tuo server web basato su java, da un certificato Comodo creato in modo indipendente e da una chiave privata utilizzando keytool (richiede JDK 1.6+)

  1. Immettere questo comando e al prompt della password immettere somepass - 'server.crt' è il certificato del server e 'server.key' è la chiave privata utilizzata per l'emissione del 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. Quindi utilizzare keytool per convertire il keystore p12 in un keystore jks: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

Quindi importa gli altri due certificati root / intermediate ricevuti da Comodo:

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

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

Ho questo in activemq config

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

Ho un paio di cert x509 e un file chiave

Come posso importare quei due da usare nei connettori ssl e ssl + stomp? Tutti gli esempi che potrei google generano sempre la chiave, ma ho già una chiave.

Ho provato

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

ma questo importa solo il certificato e non il file chiave e produce risultati

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.

Ho provato a concatenare il certificato e la chiave, ma ho ottenuto lo stesso risultato

Come posso importare la chiave?


Credi o no, keytool non fornisce una funzionalità di base come l'importazione di chiavi private nel keystore. Puoi provare questa workaround con la fusione del file PKSC12 con la chiave privata in un keystore.

O semplicemente utilizzare KeyMan più user-friendly da IBM per la gestione del keystore invece di keytool.exe.


Ecco i passaggi che ho seguito per importare la chiave in un keystore esistente: istruzioni combinate dalle risposte qui e da altri luoghi per ottenere questi passaggi che hanno funzionato per il mio keystore java:

  1. Correre

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

(Se richiesto, metti l'opzione -chain. Questo richiederà la password - è necessario fornire la password corretta altrimenti si otterrà un errore (errore di direzione o errore di padding ecc.).

  1. Ti chiederà di inserire una nuova password - devi inserire una password qui - inserisci qualsiasi cosa ma ricordala. (Supponiamo che tu entri in Aragorn).
  2. Questo creerà il file server.p12 nel formato pkcs.
  3. Ora per importarlo nel file *.jks , esegui:

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

(Molto importante - non lasciare il deststorepass e i parametri destkeypass.)
5. Ti chiederà la password dell'archivio delle chiavi src. Inserisci Aragorn e premi Invio. Il certificato e la chiave sono ora importati nel tuo keystore java esistente.


Ho usato i seguenti due passaggi che ho trovato nei commenti / post collegati nelle altre risposte:

Fase 1: convertire CERT e chiave x509 in un file pkcs12

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

Nota: assicurati di inserire una password nel file p12, altrimenti otterrai un'eccezione di riferimento null quando tenti di importarlo. (Nel caso in cui qualcun altro avesse questo mal di testa). ( Grazie, jocull! )

Nota 2: è possibile aggiungere l'opzione -chain per conservare l'intera catena di certificati. ( Grazie a Mafuba )

Passo 2: converti il ​​file pkcs12 in un keystore java

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

Finito

OPTIONAL Passo zero, creare un certificato autofirmato

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

Saluti!


Nel mio caso avevo un file pem che conteneva due certificati e una chiave privata crittografata da utilizzare nell'autenticazione SSL reciproca. Quindi il mio file PEM assomigliava a questo:

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

Ecco cosa ho fatto:

Suddividi il file in tre file separati, in modo che ognuno contenga solo una voce, iniziando con "--- BEGIN .." e terminando con "--- END ..". Supponiamo che ora abbiamo tre file: cert1.pem cert2.pem e pkey.pem

Converti pkey.pem in formato DER usando openssl e la seguente sintassi:

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

Nota che se la chiave privata è crittografata devi fornire una password (ottenerla dal fornitore del file pem originale) per convertire in formato DER, openssl ti chiederà la password in questo modo: "inserisci una pass phrase per pkey .pem: "Se la conversione ha successo, otterrai un nuovo file chiamato" pkey.der "

Creare un nuovo key store java e importare la chiave privata e i certificati:

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

(facoltativo) Verifica il contenuto del tuo nuovo keystore:

keytool -list -keystore mykeystore -storepass password

Tipo di archivio di chiavi: Provider di chiavi JKS: SUN

Il tuo keystore contiene 3 voci

cn = ..., ou = ..., o = .., 2 settembre 2014, trustedCertEntry, Impronta digitale certificato (SHA1): 2C: B8: ...

importkey, 2 settembre 2014, PrivateKeyEntry, Impronta digitale certificato (SHA1): 9C: B0: ...

cn = ..., o = ...., 2 settembre 2014, trustedCertEntry, Impronta digitale certificato (SHA1): 83:63: ...

(facoltativo) Test dei certificati e della chiave privata dal nuovo keystore sul server SSL: (È possibile attivare il debug come opzione 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..

Infine registra i tuoi certificati con HttpsURLConnection se hai intenzione di usarlo:

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

Prima conversione in p12:

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

Crea nuovo JKS da p12:

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

Sì, è davvero un fatto triste che keytool non abbia funzionalità per importare una chiave privata.

Per la cronaca, alla fine sono andato con la soluzione descritta here


Keytool in Java 6 ha questa capacità: workaround

Ecco i dettagli di base di quel post.

  1. Converti il ​​certificato esistente in PKCS12 usando OpenSSL. Quando richiesto viene richiesta una password o il 2 ° passo si lamenterà.

    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. Convertire PKCS12 in un file di 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]
    

Ho anche delle risposte.

D1) Se B ruba il certificato di A e prova a impersonare come da A a C.

  • C convaliderà l'indirizzo IP di B e scoprirà che non appartiene a C. Quindi interromperà la connessione SSL. Ovviamente, anche se C invia un messaggio crittografato, solo il Real A sarà in grado di decodificarlo.

Q2) Un certificato viene solitamente rappresentato in testo normale utilizzando il formato comune X.509. Tutte le voci sono leggibili da chiunque. Il processo di hashing viene utilizzato per firmare digitalmente un documento. La firma digitale di un certificato fa sì che l'utente finale convalidi che il certificato non è stato modificato da nessuno dopo la sua creazione. L'hashing e la crittografia del contenuto utilizzando la chiave privata dell'emittente vengono eseguiti per creare una firma digitale.







java ssl jms activemq jks