¿Cómo importar un certificado .cer en un almacén de claves de Java?

226

Durante el desarrollo de un cliente de servicio web Java me encontré con un problema. La autenticación para el servicio web está utilizando un certificado de cliente, un nombre de usuario y una contraseña. El certificado de cliente que recibí de la compañía detrás del servicio web está en .cerformato. Cuando inspecciono el archivo usando un editor de texto, tiene los siguientes contenidos:

-----BEGIN CERTIFICATE-----
[Some base64 encoded data]
-----END CERTIFICATE-----

Puedo importar este archivo como un certificado en Internet Explorer (¡sin tener que ingresar una contraseña!) Y usarlo para autenticarme con el servicio web.

Pude importar este certificado a un almacén de claves eliminando primero la primera y la última línea, convirtiéndome en líneas nuevas de Unix y ejecutando una decodificación base64. El archivo resultante se puede importar a un almacén de claves (usando el keytoolcomando). Cuando enumero las entradas en el almacén de claves, esta entrada es del tipo trustedCertEntry. Debido a este tipo de entrada (?), No puedo usar este certificado para autenticarme con el servicio web. Estoy empezando a pensar que el certificado proporcionado es un certificado público que se está utilizando para la autenticación ...

Una solución que he encontrado es importar el certificado en IE y exportarlo como un .pfxarchivo. Este archivo puede cargarse como un almacén de claves y puede usarse para autenticarse con el servicio web. Sin embargo, no puedo esperar que mis clientes realicen estos pasos cada vez que reciben un nuevo certificado. Entonces me gustaría cargar el .cerarchivo directamente en Java. ¿Alguna idea?

Información adicional: la compañía detrás del servicio web me dijo que el certificado debería solicitarse (usando IE y el sitio web) desde la PC y el usuario que importaría el certificado más tarde.

Jan-Pieter
fuente

Respuestas:

317
  • Si desea autenticarse, necesita la clave privada; no hay otra opción.
  • Un certificado es una clave pública con propiedades adicionales (como nombre de la empresa, país, ...) que está firmada por alguna autoridad de certificación que garantiza que las propiedades adjuntas son verdaderas.
  • .CERLos archivos son certificados y no tienen la clave privada. La clave privada se proporciona con un .PFX keystorearchivo normalmente. Si realmente se autentica es porque ya había importado la clave privada.
  • Normalmente puede importar .CERcertificados sin ningún problema con

    keytool -importcert -file certificate.cer -keystore keystore.jks -alias "Alias" 
lujop
fuente
3
Resulta que la clave privada está siendo generada por un complemento para IE. La única solución por ahora es importar el certificado en IE y exportar un archivo .pfx.
Jan-Pieter
55
Los archivos .CER tienen la clave pública. No tienen la clave privada. Sugerir edición ..
KyleM
66
¿Qué hace -alias aquí?
salto
55
:( -> error de keytool: java.lang.Exception: entrada no es un certificado X.509
nigromante
1
@hop Un almacén de claves de Java puede tener múltiples certificados, cada uno con un alias diferente para identificarlo. Puede usarlo como referencia para identificarlo y / o recuperarlo programáticamente por nombre de alias.
lujop
85

Importar el .cerarchivo de certificado descargado del navegador (abra la url y busque detalles) en el almacén de claves de cacertsjava_home\jre\lib\security me funcionó, en lugar de los intentos de generar y usar mi propio almacén de claves.

  1. Ir a tu java_home\jre\lib\security
  2. ( Windows ) Abra la línea de comando de administración usando cmdy CTRL+ SHIFT+ENTER
  3. Ejecute keytool para importar el certificado:
    • (Reemplazar yourAliasNamey path\to\certificate.cerrespectivamente)

 ..\..\bin\keytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias yourAliasName -file path\to\certificate.cer

De esta manera, no tiene que especificar ninguna opción JVM adicional y el certificado debe ser reconocido por el JRE.

jediz
fuente
ruta \ a \ cert. Si mi archivo está en el escritorio, ¿cómo puedo enrutarlo? C: / user / desktop / or ../../../../desktop/filename
Jesse
en MacOS / Linux este comando funciona con sudo. Gracias. pero que es noprompt param? No lo usé y todavía lo logré.
Evgeniy Mishustin
Tenga en cuenta que cuando se utiliza el JDK para el desarrollo, la ruta correcta es java_home\jdk_x.xx\jre\lib\security Para una ruta absoluta, utilice la barra invertida, por ejemplo, las "C:\myCert.crt"comillas son opcionales si la ruta no contiene espacios en blanco.
jp-jee
Un millón de gracias
vikingsteve
Pregunta: ¿Qué pasa con la clave privada? La discusión es sobre certificados de clientes. Tengo entendido que uno necesita crear una CSR con una clave privada, luego recibir un certificado de cliente de la compañía del sitio web remoto y luego hacer coincidir el certificado del cliente con la clave privada. Su respuesta no parece mencionar nada sobre la clave privada. Sólo preguntaba.
user2367418
51

Aquí está el código que he estado usando para importar programáticamente archivos .cer en un nuevo KeyStore.

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
//VERY IMPORTANT.  SOME OF THESE EXIST IN MORE THAN ONE PACKAGE!
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;

//Put everything after here in your function.
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);//Make an empty store
InputStream fis = /* insert your file path here */;
BufferedInputStream bis = new BufferedInputStream(fis);

CertificateFactory cf = CertificateFactory.getInstance("X.509");

while (bis.available() > 0) {
    Certificate cert = cf.generateCertificate(bis);
    trustStore.setCertificateEntry("fiddler"+bis.available(), cert);
}
Patrick M
fuente
20

No debería tener que hacer ningún cambio en el certificado. ¿Estás seguro de que estás ejecutando el comando de importación correcto?

Lo siguiente funciona para mí:

keytool -import -alias joe -file mycert.cer -keystore mycerts -storepass changeit

donde mycert.cer contiene:

-----BEGIN CERTIFICATE-----
MIIFUTCCBDmgAwIBAgIHK4FgDiVqczANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
...
RLJKd+SjxhLMD2pznKxC/Ztkkcoxaw9u0zVPOPrUtsE/X68Vmv6AEHJ+lWnUaWlf
zLpfMEvelFPYH4NT9mV5wuQ1Pgurf/ydBhPizc0uOCvd6UddJS5rPfVWnuFkgQOk
WmD+yvuojwsL38LPbtrC8SZgPKT3grnLwKu18nm3UN2isuciKPF2spNEFnmCUWDc
MMicbud3twMSO6Zbm3lx6CToNFzP
-----END CERTIFICATE-----
dogbane
fuente
2
Cuando trato de importar el certificado no modificado en el almacén de claves, aparece el error "error de herramienta clave: java.lang.Exception: no ingrese un certificado X.509". Después de modificar el certificado de la manera que describí en mi publicación, puedo importar el certificado sin errores con un comando similar al suyo. Sin embargo, se importa como TrustedCertEntry y no se utiliza al acceder al servicio web.
Jan-Pieter
¿Puede agregar el comando la excepción a la pregunta? ¿Está seguro de que está especificando un alias en su comando de importación?
dogbane
No olvide ejecutar cmd como administrador si está utilizando Windows
SilentBob470
9

Una herramienta GUI de código abierto está disponible en keystore-explorer.org

KeyStore Explorer

KeyStore Explorer es un reemplazo de GUI de código abierto para las herramientas de línea de comandos de Java keytool y jarsigner. KeyStore Explorer presenta su funcionalidad, y más, a través de una interfaz gráfica de usuario intuitiva.

Las siguientes pantallas ayudarán (son del sitio oficial)

Pantalla predeterminada que obtiene al ejecutar el comando:

shantha@shantha:~$./Downloads/kse-521/kse.sh

ingrese la descripción de la imagen aquí

Y vaya a Examinee Examine a URLopción y luego dar la URL web que desea importar.

La ventana de resultados será la siguiente si le das un enlace al sitio de Google. ingrese la descripción de la imagen aquí

Este es uno de los casos de uso y el resto depende del usuario (todos los créditos van al keystore-explorer.org )

Shantha Kumara
fuente
7

El certificado que ya tiene es probablemente el certificado del servidor, o el certificado utilizado para firmar el certificado del servidor. Lo necesitará para que su cliente de servicio web pueda autenticar el servidor.

Pero si además necesita realizar la autenticación del cliente con SSL, entonces necesita obtener su propio certificado, para autenticar su cliente de servicio web. Para esto necesita crear una solicitud de certificado; el proceso implica crear su propia clave privada y la clave pública correspondiente, y adjuntar esa clave pública junto con parte de su información (correo electrónico, nombre, nombre de dominio, etc.) a un archivo llamado solicitud de certificado. Luego, envía esa solicitud de certificado a la compañía que ya la solicitó, y ellos crearán su certificado, firmando su clave pública con su clave privada, y le enviarán un archivo X509 con su certificado, que puede ahora agregue a su almacén de claves y estará listo para conectarse a un servicio web mediante SSL que requiere autenticación del cliente.

Para generar su solicitud de certificado, use "keytool -certreq -alias -file -keypass -keystore". Envíe el archivo resultante a la compañía que lo firmará.

Cuando recupere su certificado, ejecute "keytool -importcert -alias -keypass -keystore".

Es posible que necesite usar -storepass en ambos casos si el almacén de claves está protegido (lo cual es una buena idea).

Chochos
fuente
5

Aquí hay un script que utilicé para importar por lotes un montón de archivos crt en el directorio actual en el almacén de claves de Java. Simplemente guarde esto en la misma carpeta que su certificado y ejecútelo así:

./import_all_certs.sh

import_all_certs.sh

KEYSTORE="$(/usr/libexec/java_home)/jre/lib/security/cacerts";

function running_as_root()
{
  if [ "$EUID" -ne 0 ]
    then echo "NO"
    exit
  fi

  echo "YES"
}

function import_certs_to_java_keystore
{
  for crt in *.crt; do 
    echo prepping $crt 
    keytool -import -file $crt -storepass changeit -noprompt --alias alias__${crt} -keystore $KEYSTORE
    echo 
  done
}

if [ "$(running_as_root)" == "YES" ]
then
  import_certs_to_java_keystore
else
  echo "This script needs to be run as root!"
fi
Brad Parks
fuente
1

Así es como esto funcionó para mí:

  1. Guarde como .txt los datos del certificado en el siguiente formato en un editor de texto

    ----- COMENZAR CERTIFICADO ----- [datos serializados por microsoft] ----- FINALIZAR CERTIFICADO -----

  2. Configuración del navegador Chrome abierto (este paso también podría funcionar con otros navegadores)> mostrar configuración avanzada> HTTPS / SSL> administrar certificados Importe el .txt en el paso 1
  3. Seleccione y exporte ese certificado en formato codificado Base-64. Guárdelo como .cer
  4. Ahora puede usar keytool o Portecle para importarlo a su almacén de claves de Java
code4kix
fuente