utiliza respuesta recomienda públicas propietario migrar las kit herramienta formato existe ejemplo desarrollo crear coinciden claves certificados certificado archivo almacén almacen administración java ssl jms activemq jks

respuesta - keystore java ejemplo



¿Cómo importar un certificado x509 existente y una clave privada en el almacén de claves Java para usar en SSL? (10)

Tengo esto en configuración de activemq

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

Tengo un par de certificado x509 y un archivo de clave

¿Cómo importo esos dos para usar en los conectores ssl y ssl + stomp? Todos los ejemplos que pude google siempre generan la clave ellos mismos, pero ya tengo una clave.

Yo he tratado

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

pero esto solo importa el certificado y no el archivo de clave y los resultados 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.

Intenté concatenar el certificado y la clave pero obtuve el mismo resultado

¿Cómo importo la clave?


En función de las respuestas anteriores, aquí se muestra cómo crear un nuevo almacén de claves para su servidor web basado en Java, a partir de un certificado de Comodo creado independientemente y una clave privada utilizando la herramienta de claves (requiere JDK 1.6+)

  1. Emita este comando y en el indicador de contraseña ingrese somepass - ''server.crt'' es el certificado de su servidor y ''server.key'' es la clave privada que usó para emitir el 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. A continuación, utilice keytool para convertir el almacén de claves p12 en un almacén de claves jks: keytool -importkeystore -deststorepass somepass -destkeypass somepass -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass somepass

Luego importe los otros dos certificados raíz / intermedios que recibió de Comodo:

  1. Importar COMODORSAAddTrustCA.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


En mi caso, tenía un archivo pem que contenía dos certificados y una clave privada encriptada para usar en la autenticación SSL mutua. Entonces mi archivo de pem se veía así:

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

Aquí esta lo que hice:

Divida el archivo en tres archivos separados, de modo que cada uno contenga solo una entrada, comenzando con "--- BEGIN .." y terminando con las líneas "--- END ..". Supongamos que ahora tenemos tres archivos: cert1.pem cert2.pem y pkey.pem

Convierta pkey.pem en formato DER utilizando openssl y la siguiente sintaxis:

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

Tenga en cuenta que si la clave privada está encriptada, debe proporcionar una contraseña (obtenerla del proveedor del archivo pem original) para convertirla a formato DER, openssl le pedirá la contraseña de la siguiente manera: "enter a pass phraze for pkey" .pem: "Si la conversión es exitosa, obtendrás un nuevo archivo llamado" pkey.der "

Cree un nuevo almacén de claves java e importe la clave privada y los certificados:

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

(opcional) Verifique el contenido de su nuevo almacén de claves:

keytool -list -keystore mykeystore -storepass password

Tipo de almacén de claves: JKS Proveedor de almacén de claves: SUN

Tu keystore contiene 3 entradas

cn = ..., ou = ..., o = .., 2 de septiembre de 2014, trustedCertEntry, Certificado de huella digital (SHA1): 2C: B8: ...

importkey, 2 de septiembre de 2014, PrivateKeyEntry, Certificado de huella digital (SHA1): 9C: B0: ...

cn = ..., o = ...., 2 de septiembre de 2014, trustedCertEntry, Certificado de huella digital (SHA1): 83:63: ...

(opcional) Pruebe sus certificados y claves privadas desde su nuevo almacén de claves contra su servidor SSL: (Es posible que desee habilitar la depuración como una opción de 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..

Finalmente registre sus certificados con HttpsURLConnection si planea 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);


Estos son los pasos que seguí para importar la clave a un almacén de claves existente: instrucciones combinadas de las respuestas aquí y de otros lugares para obtener estos pasos que funcionaron para mi keystore de Java:

  1. correr

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

(Si es necesario, ponga la opción -chain. Poniendo eso falló para mí). Esto le pedirá la contraseña: debe dar la contraseña correcta, de lo contrario recibirá un error (error de encabezado o error de relleno, etc.).

  1. Le pedirá que ingrese una nueva contraseña; debe ingresar una contraseña aquí; ingrese cualquier cosa, pero no la recuerde. (Supongamos que ingresas a Aragorn).
  2. Esto creará el archivo server.p12 en el formato pkcs.
  3. Ahora para importarlo en el archivo *.jks ejecutar:

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -destkeystore yourexistingjavakeystore.jks -deststoretype JKS -deststorepass existingjavastorepassword -destkeypass existingjavastorecontraseña

(Muy importante: no omita los parámetros deststorepass y destkeypass).
5. Le pedirá la contraseña de la clave de almacenamiento src. Ingrese Aragorn y presione enter. El certificado y la clave ahora se importan a su almacén de claves java existente.


Keytool en Java 6 tiene esta capacidad: workaround

Aquí están los detalles básicos de esa publicación.

  1. Convierta el certificado existente en un PKCS12 usando OpenSSL. Se requiere una contraseña cuando se le solicita o el segundo paso se quejará.

    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. Convierta el PKCS12 en un archivo de 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]


Las respuestas anteriores señalan correctamente que solo puede hacer esto con las herramientas estándar JDK convirtiendo primero el archivo JKS al formato PKCS # 12. Si está interesado, armé una utilidad compacta para importar claves derivadas de OpenSSL en un almacén de claves con formato JKS sin tener que convertir primero el almacén de claves a PKCS # 12: http://commandlinefanatic.com/cgi-bin/showarticle.cgi?article=art049

Utilizarías la utilidad vinculada así:

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

(Firme el CSR, recupere 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


Lo creas o no, keytool no proporciona una funcionalidad básica como importar una clave privada al almacén de claves. Puede probar esta workaround con la fusión del archivo PKSC12 con clave privada a un almacén de claves.

O simplemente use KeyMan más amigable de IBM para el manejo del almacén de claves en lugar de keytool.exe.


Primero conviértase en p12:

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

Crear nuevo JKS desde p12:

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


Sí, de hecho es un hecho lamentable que keytool no tenga ninguna funcionalidad para importar una clave privada.

Para el registro, al final fui con la solución descrita here


Usé los siguientes dos pasos que encontré en los comentarios / publicaciones vinculadas en las otras respuestas:

Paso uno: Convertir x509 Cert y Key en un archivo pkcs12

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

Nota: asegúrese de poner una contraseña en el archivo p12; de lo contrario, obtendrá una excepción de referencia nula cuando intente importarlo. (En caso de que alguien más tuviera este dolor de cabeza). ( Gracias jocull! )

Nota 2: es posible que desee agregar la opción -chain para conservar la cadena de certificados completa. ( Gracias Mafuba )

Paso dos: Convierta el archivo pkcs12 a un keystore de java

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

Terminado

OPCIONAL Paso cero, crear certificado autofirmado

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

¡Aclamaciones!


Y uno más:

#!/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"