La utilidad keytool incluida en el Java Development Kit (JDK) crea un par de claves dentro de un almacén de claves de Java y lo convierte en un CSR (Certificate Signing Request), el bloque codificado que una Autoridad de Certificación (CA) lee para identificarlo antes de emitir un certificado. En cuanto a la firma de código, el uso legítimo de keytool cambió el 1 de junio de 2023. Esta guía expone primero la norma y luego repasa los comandos de keytool que siguen siendo correctos: contra un almacén de claves de software para firma interna, y contra un token de hardware o HSM mediante PKCS#11.
Las claves de firma de código deben generarse en hardware
Desde el 1 de junio de 2023, los Requisitos de Referencia de Firma de Código del CA/Browser Forum exigen que la clave privada de todo certificado de firma de código de confianza pública se genere y almacene en un módulo criptográfico de hardware que cumpla con FIPS 140-2 Nivel 2, Common Criteria EAL4+, o un estándar equivalente. La clave debe ser no exportable. Esto se aplica tanto a los certificados estándar (Validación de Organización) como a los de Validación Extendida. Los certificados EV de firma de código siempre requirieron hardware; el cambio de 2023 extendió la misma norma a los certificados estándar. Esos mismos requisitos establecen un tamaño mínimo de clave de RSA 3072 para los certificados de firma de código, vigente desde el 1 de junio de 2021.
La consecuencia para esta página es directa. Un archivo de almacén de claves que keytool crea en su portátil o servidor, ya sea en formato PKCS12 o en el formato JKS más antiguo, contiene una clave de software. Un CSR generado a partir de él no es aceptado por una Autoridad de Certificación pública para un certificado de firma de código. Las Autoridades de Certificación han dejado de admitir la generación de claves en el navegador y los archivos de claves descargables para estos productos. Su clave ahora se origina en uno de estos dos lugares:
- Un token preconfigurado que la CA le envía. La CA genera el par de claves y el CSR en un token USB certificado en su propio lado, carga el certificado emitido en él y le envía el token por correo. No hay ningún CSR que usted deba crear.
- Su propio HSM o token, con atestación de clave. Usted genera la clave dentro del dispositivo, produce un CSR a partir de ella y presenta un archivo de atestación que demuestra a la CA que la clave se creó en hardware conforme y que no puede exportarse. Se requieren ambas partes; un CSR sin atestación válida es rechazado.
Qué ruta se aplica se decide al momento de realizar el pedido. Para la comparación, consulte los métodos de entrega de certificados de firma de código. Si ya cuenta con hardware conforme, siga la guía correspondiente a su dispositivo: generación de CSR y atestación con YubiKey 5 FIPS o la guía de CSR y atestación de Luna Network Attached HSM v7.x.
Dónde sigue encajando keytool
Nada de lo anterior deja obsoleto a keytool. Sigue siendo la herramienta adecuada en tres situaciones, y solo la primera produce un CSR que puede enviar a una CA pública:
- Como interfaz PKCS#11 hacia su token o HSM. keytool habla PKCS#11 de forma nativa. Apúntelo hacia la biblioteca PKCS#11 de su proveedor y la clave nunca sale del dispositivo, mientras que el conocido comando -certreq sigue produciendo el CSR. Los comandos están en la sección de hardware más abajo.
- Para firma interna o empresarial. Si firma software interno con la propia CA de su organización, su política interna rige el almacenamiento de claves, no los Requisitos de Referencia públicos. Un almacén de claves de software es una opción normal en ese caso.
- Para práctica. Es más fácil acertar con el nombre del sujeto en el primer intento si ya ha ejecutado los avisos una vez contra un almacén de claves desechable.
Una limitación que conviene conocer antes de empezar: keytool no genera atestación de clave. La atestación la produce la herramienta propia del proveedor del token o HSM, así que incluso en la vía PKCS#11 usará la utilidad del proveedor para ese archivo y keytool únicamente para el CSR.
Genere el CSR con keytool
Si ya ha creado su CSR y la Autoridad de Certificación ha emitido el certificado, pase directamente a importar la respuesta de la CA, el paso que falla silenciosamente cuando el alias no coincide.
keytool viene con el JDK, así que instale un JDK actual primero si no dispone de uno. JDK 25 es la versión actual de soporte a largo plazo y JDK 26 es la versión actual de soporte a corto plazo. Los comandos siguientes funcionan en JDK 17 y posteriores, y las diferencias de versión relevantes se indican donde se producen. Confirme que la herramienta está en su ruta:
java -version
keytool -help
jarsigner -version
Un Java Runtime Environment por sí solo no es suficiente, y un keytool funcional no es prueba de que tenga un JDK: el antiguo Oracle JRE 8 incluye keytool pero no jarsigner. Ejecute ahora los tres comandos. Si los dos primeros responden y el tercero no, está usando un JRE, y instalar un JDK en ese momento es más fácil que descubrirlo cuando vaya a firmar.
Paso 1: Cree el almacén de claves y el par de claves
Ejecute esto en una terminal, o en el Símbolo del sistema o PowerShell en Windows, desde el directorio donde desee que resida el archivo del almacén de claves:
keytool -genkeypair -alias codesign -keyalg RSA -keysize 3072 -storetype PKCS12 -keystore codesign.p12
Cuatro detalles de ese comando difieren de instrucciones anteriores, y cada uno importa:
- -genkeypair, no -genkey. La antigua notación -genkey aún se ejecuta y keytool no muestra ninguna advertencia al respecto, pero solo se mantiene en el código fuente como alias heredado y ya no aparece en ningún lugar de la documentación del JDK. Escriba -genkeypair.
- -storetype PKCS12, no JKS. JKS es el formato de almacén de claves propietario de Oracle. PKCS12 es el estándar de la industria y ha sido el predeterminado del JDK desde Java 9. Si de todos modos crea un almacén de claves JKS, keytool le advertirá en cada comando que lo utilice: «The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format.»
- El nombre del archivo no determina el formato. Nombrar un archivo keystore.jks no lo convierte en un almacén JKS. keytool toma el tipo de -storetype, o de la propiedad keystore.type del archivo de seguridad del JDK cuando se omite. En JDK 9 y posteriores, esa propiedad es pkcs12, así que un comando que escribe en keystore.jks sin -storetype produce silenciosamente un archivo PKCS12 con un nombre engañoso.
- -keysize 3072, no 2048. Los Requisitos de Referencia establecen RSA 3072 como mínimo para la firma de código, así que una solicitud de 2048 bits se rechaza. Los JDK actuales usan por defecto 3072 para RSA, pero JDK 17 y anteriores usan por defecto 2048, así que indique la opción explícitamente y el comando se comportará igual en todas partes.
El alias, codesign en el ejemplo, es la etiqueta de esta entrada dentro del almacén de claves. Elija algo que reconozca fácilmente y anótelo: todos los comandos posteriores lo necesitan, y una discrepancia es lo que rompe la importación del certificado descrita más adelante.
También se admite una clave ECDSA. Sustituya -keyalg EC -groupname secp256r1 por las opciones de RSA si prefiere P-256, y confirme con su CA que el producto que ha pedido admite ECDSA.
Paso 2: Responda las preguntas que construyen su nombre distinguido
keytool pide una contraseña del almacén de claves dos veces y luego formula seis preguntas en este orden exacto. El orden importa: la segunda pregunta solicita la unidad organizativa, no la organización, y las guías antiguas lo listan de forma incorrecta, por lo que un lector que escribe ahí el nombre de la empresa lo coloca en el componente equivocado del nombre.
- ¿Cuáles son su nombre y apellido? Esto se convierte en el Common Name (CN), a pesar del enunciado. Para un certificado de firma de código, el CN es la identidad del editor que verán los usuarios, así que introduzca el nombre legal exacto de su organización, o su propio nombre legal completo para un certificado individual. No introduzca aquí un nombre de dominio.
- ¿Cuál es el nombre de su unidad organizativa? El departamento, por ejemplo IT. No pulse Intro para omitirlo: keytool escribirá entonces el valor literal Unknown en el nombre, y OU=Unknown terminará en su CSR. Si no desea ninguna unidad organizativa, use la forma -dname descrita más abajo y omita el componente OU en la cadena.
- ¿Cuál es el nombre de su organización? El nombre legal registrado, escrito tal como aparece en los registros oficiales. La CA lo verifica contra registros públicos.
- ¿Cuál es el nombre de su ciudad o localidad? La ciudad de registro, escrita en su totalidad.
- ¿Cuál es el nombre de su estado o provincia? El nombre completo, no una abreviatura.
- ¿Cuál es el código de país de dos letras para esta unidad? El código ISO, por ejemplo US.
keytool imprime entonces el nombre ensamblado y le pide que lo confirme:
Is CN=Example LLC, OU=IT, O=Example LLC, L=Miami, ST=Florida, C=US correct?
[no]:
La respuesta predeterminada es no, así que pulsar Intro le devuelve a las seis preguntas. Escriba yes para aceptar. Lea la línea con atención primero: este es el nombre distinguido completo, no solo el Common Name, y cada componente de él se incluye en el CSR.
No existe una contraseña de clave separada en un almacén de claves PKCS12. Las guías antiguas terminan este paso con «introduzca una contraseña para la clave», que es el comportamiento de JKS. En un almacén de claves PKCS12, la contraseña de la clave es la contraseña del almacén, y si pasa -keypass con un valor diferente, keytool se lo indica así: «Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified -keypass value.»
Para omitir por completo los avisos, proporcione el nombre completo con -dname. Mantenga el valor entre un único par de comillas rectas:
keytool -genkeypair -alias codesign -keyalg RSA -keysize 3072 -storetype PKCS12 -keystore codesign.p12 -dname "CN=Example LLC, OU=IT, O=Example LLC, L=Miami, ST=Florida, C=US"
Deje fuera -storepass de la línea de comandos y deje que keytool le pida la contraseña. Pasar una contraseña como argumento la escribe en el historial de su shell y la expone a cualquiera que pueda listar los procesos en ejecución.
Paso 3: Cree el CSR
El almacén de claves ahora contiene una clave privada y un certificado autofirmado temporal. Convierta esa entrada en una solicitud de certificado:
keytool -certreq -alias codesign -keystore codesign.p12 -file codesign.csr
Introduzca la contraseña del almacén de claves cuando se le solicite. No necesita -storetype aquí: keytool detecta el formato de un archivo de almacén de claves que ya existe. El alias debe ser el del paso 1, porque el CSR se firma con la clave privada de esa entrada.
Este comando no crea una clave privada. La clave se creó en el paso 1 y permanece dentro del almacén de claves, razón por la cual el archivo del almacén de claves y su contraseña son ahora tan sensibles como la propia clave. Cualquiera que tenga ambos puede firmar software en su nombre.
Paso 4: Verifique el CSR antes de enviarlo
Un CSR rechazado cuesta un ciclo de validación, así que decodifíquelo y léalo de vuelta:
keytool -printcertreq -file codesign.csr
Confirme tres cosas en la salida. La línea Subject debe listar sus datos en los componentes correctos, con el nombre legal de la organización en O y la identidad del editor en CN. La línea de la clave pública debe indicar 3072-bit RSA key o mayor. El algoritmo de firma debe ser un algoritmo SHA-2: los JDK actuales firman una solicitud RSA de 3072 bits con SHA384withRSA y los más antiguos usan SHA256withRSA, y ambos son válidos. Ese algoritmo solo demuestra que usted posee la clave privada, y no es el algoritmo que la CA usará para firmar su certificado.
También puede pegar la solicitud en nuestro decodificador de CSR para leer los mismos campos en el navegador.
Al enviar la solicitud, abra el archivo en un editor de texto plano y copie todo, incluidas la primera y la última línea. keytool escribe estos marcadores exactos, con cinco guiones a cada lado:
-----BEGIN NEW CERTIFICATE REQUEST-----
MIID3TCCAkUCAQAwaDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExDjAM
...base64 encoded request...
-----END NEW CERTIFICATE REQUEST-----
La redacción NEW CERTIFICATE REQUEST es normal en la salida de keytool y los formularios de inscripción la aceptan. Si su editor ha reemplazado alguna secuencia de guiones por un guion largo, la solicitud será rechazada: vuelva a escribir los marcadores como guiones simples o copie el archivo con un editor de código en su lugar.
Genere el CSR en un token o HSM con keytool
Esta es la vía que produce un CSR sobre el que una CA pública puede actuar. keytool se comunica con un token de hardware a través del proveedor SunPKCS11, de modo que el par de claves se crea dentro del dispositivo y nunca existe como archivo. Comience escribiendo un pequeño archivo de configuración, por ejemplo token.cfg, que nombre su token y apunte a la biblioteca PKCS#11 que instaló su proveedor:
name = token
library = /usr/local/lib/libeToken.so
Esas dos líneas, name y library, son las únicas obligatorias. La ruta de la biblioteca es específica del proveedor y varía según el sistema operativo, así que tómela de la documentación de su token en lugar de este ejemplo. En Windows es un DLL bajo el directorio del sistema. Sin una línea slot, el proveedor se conecta a la primera ranura que informa el dispositivo, que es lo que desea cuando hay un único token conectado. Si tiene más de un lector o token, añada bien slotListIndex con la posición en esa lista, contando desde cero, o bien slot con el ID numérico de ranura que imprime la utilidad de su proveedor. Solo uno de los dos puede aparecer en el archivo, y un ID de ranura no es el mismo número que una posición en la lista, así que no adivine con slot = 0.
Liste lo que hay en el dispositivo. El token proporciona el alias, así que necesita esto antes que nada:
keytool -list -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg token.cfg
-keystore NONE es obligatorio siempre que el almacén de claves no sea un archivo, y el aviso de contraseña está solicitando el PIN del token. keytool también acepta -addprovider SunPKCS11 -providerarg token.cfg en lugar del par -providerClass y -providerArg; ambas formas funcionan, y la documentación de las Autoridades de Certificación suele mostrar la más antigua.
Con el alias en mano, genere la clave en el dispositivo y luego solicite el CSR contra ella:
keytool -genkeypair -alias codesign -keyalg RSA -keysize 3072 -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg token.cfg -dname "CN=Example LLC, O=Example LLC, L=Miami, ST=Florida, C=US"
keytool -certreq -alias codesign -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg token.cfg -file codesign.csr
Se aplican dos advertencias. Algunos tokens no permiten la generación de claves mediante PKCS#11 y esperan que use la utilidad propia del proveedor, lo cual está bien: keytool aún puede crear el CSR contra una clave que generó la herramienta del proveedor. Y keytool no puede producir el archivo de atestación que su CA solicitará, así que genérelo con las herramientas del proveedor al mismo tiempo que la clave, siguiendo la guía de YubiKey o de Luna HSM.
Importe la respuesta de la CA en el mismo alias
Cuando llega el certificado, tiene que volver a la entrada que generó el CSR. Si lo importa en cualquier otro lugar, keytool seguirá informando éxito mientras produce un almacén de claves que no puede firmar, así que lea esta sección antes de ejecutar nada.
Importe primero la raíz de la CA y cualquier certificado intermedio, cada uno bajo su propio alias:
keytool -importcert -trustcacerts -alias caroot -file root.crt -keystore codesign.p12
keytool imprime el certificado que está a punto de almacenar y pregunta Trust this certificate? con no como valor predeterminado, así que escriba yes. Compruebe la huella digital con la que publica su Autoridad de Certificación antes de responder.
Si omite la importación de la raíz, el siguiente comando falla con un mensaje que no ofrece ninguna pista sobre la causa:
keytool error: java.lang.Exception: Failed to establish chain from reply
Ahora importe su certificado emitido usando el mismo alias que usó en el paso 1:
keytool -importcert -alias codesign -file codesign.crt -keystore codesign.p12
El mensaje que desea ver es Certificate reply was installed in keystore. Eso significa que keytool reconoció una clave privada existente bajo ese alias y adjuntó a ella el certificado emitido y su cadena.
Si en cambio inventa un alias nuevo, keytool acepta el archivo e imprime Certificate was added to keystore. Eso parece un éxito y no lo es. keytool ha almacenado el certificado como una entrada de confianza independiente sin ninguna clave privada detrás, y esa entrada nunca podrá firmar nada. El alias original, mientras tanto, aún contiene el certificado autofirmado temporal del paso 1. Compruebe cuál de los dos tiene:
keytool -list -keystore codesign.p12
Su alias de firma debe aparecer listado como PrivateKeyEntry. Un alias mostrado como trustedCertEntry es el error descrito antes. Elimínelo con keytool -delete -alias wrongalias -keystore codesign.p12 y repita la importación contra el alias correcto. Añada -v al comando de listado para confirmar que la entrada ahora lleva una cadena de certificados completa en lugar de un único certificado autofirmado.
En un token de hardware normalmente no hay nada que importar, porque la CA carga el certificado en el dispositivo antes de enviarlo. Si su CA le envía un archivo de certificado para una clave que usted generó en su propio HSM, use el mismo comando -importcert con las opciones PKCS#11 de la sección anterior.
Firme un archivo JAR con el certificado
El objetivo de colocar un certificado de firma de código en un almacén de claves de Java es firmar archivos JAR con jarsigner, que también viene incluido en el JDK. Con el certificado instalado bajo el alias correcto:
jarsigner -keystore codesign.p12 -tsa https://your-ca-timestamp-url application.jar codesign
Pase siempre -tsa con la URL de sellado de tiempo que publica su Autoridad de Certificación. Un sello de tiempo registra que el JAR se firmó mientras el certificado seguía siendo válido, de modo que la firma sigue funcionando después de que el certificado caduque. Sin uno, cada copia de su software deja de validarse el día en que el certificado expira.
Cuando la clave reside en un token, apunte jarsigner a PKCS#11 exactamente como lo hace keytool:
jarsigner -keystore NONE -storetype PKCS11 -providerClass sun.security.pkcs11.SunPKCS11 -providerArg token.cfg -tsa https://your-ca-timestamp-url application.jar codesign
Si el token tiene demasiado poco espacio para la cadena de certificados completa, proporciónela por separado con -certchain. Compruebe el resultado después:
jarsigner -verify -verbose -certs application.jar
Una ejecución exitosa imprime jar verified junto con el nombre distinguido del firmante y los detalles del sellado de tiempo. Los JDK actuales usan SHA-384 como algoritmo de resumen predeterminado, así que rara vez necesita establecer -digestalg o -sigalg manualmente.
Otras formas de crear esta solicitud se explican en las guías de OpenSSL, CertReq, Microsoft Management Console, y macOS Keychain Access, y la misma norma de hardware se aplica a todas ellas. Consulte también nuestro conjunto completo de tutoriales de firma de código y la visión general de generación de CSR para certificados de firma de código. Si necesita un CSR de keytool para un certificado de sitio web en lugar de uno de firma de código, siga la guía de Tomcat o de JBoss en su lugar.
Preguntas frecuentes
Solo si keytool generó la clave dentro de un token de hardware o HSM mediante PKCS#11, y puede proporcionar la atestación que solicita la Autoridad de Certificación. Un CSR creado a partir de un archivo de almacén de claves ordinario en su equipo es una clave de software, y desde el 1 de junio de 2023 las CA públicas no emiten certificados de firma de código contra claves de software. Los almacenes de claves de software siguen siendo válidos para firmar con una CA interna o empresarial.
Use -genkeypair. La notación -genkey es un alias heredado que el JDK todavía acepta sin ninguna advertencia, pero ha estado ausente de la documentación durante muchas versiones. Ambos hacen lo mismo hoy en día; solo uno de ellos está documentado.
Use PKCS12. Es un formato estándar de la industria y ha sido el tipo de almacén de claves predeterminado del JDK desde Java 9, mientras que JKS es propietario de Oracle y hace que keytool imprima una advertencia de migración en cada comando. La extensión del archivo no tiene ningún efecto: keytool decide el formato a partir de -storetype, o de la propiedad de seguridad keystore.type cuando se omite, así que un archivo llamado keystore.jks creado en un JDK moderno suele ser un archivo PKCS12. Para convertir un almacén de claves existente, ejecute keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype pkcs12.
RSA de 3072 bits o mayor, que los Requisitos de Referencia de Firma de Código exigen desde el 1 de junio de 2021, o una clave ECDSA equivalente como P-256. Indique -keysize 3072 explícitamente, porque JDK 17 y anteriores usan por defecto 2048 bits y esa solicitud se rechaza.
Casi con certeza importó la respuesta de la CA en un alias nuevo en lugar de en el alias que generó el CSR. keytool entonces lo almacena como un certificado de confianza independiente sin ninguna clave privada adjunta, e imprime Certificate was added to keystore, lo cual parece un éxito. Ejecute keytool -list -keystore codesign.p12: el alias de firma debe aparecer como PrivateKeyEntry, no como trustedCertEntry. Elimine la entrada incorrecta e importe de nuevo con el alias original, y debería ver Certificate reply was installed in keystore.
keytool no puede construir una ruta desde su certificado emitido hasta un certificado en el que ya confía. Importe primero la raíz y los certificados intermedios de la CA en el mismo almacén de claves, cada uno bajo su propio alias con -importcert -trustcacerts, y luego importe su certificado de nuevo. Alternativamente, importe un único archivo que contenga su certificado seguido de los intermedios y la raíz.
No. Un certificado de firma de código se identifica por su uso extendido de clave de firma de código, no por una cadena de herramientas, así que el mismo certificado firma archivos JAR con jarsigner y ejecutables de Windows con signtool. Lo que sí elige al hacer el pedido es el método de entrega, que decide si la CA le envía un token preconfigurado o si usted genera la clave en hardware que ya posee.
Con un token o HSM, la clave está dentro del dispositivo y no puede copiarse hacia afuera, que es todo el sentido del requisito. Con un almacén de claves de software usado para firma interna, la clave reside en el archivo del almacén de claves, así que el archivo y su contraseña juntos son el secreto: guárdelos en una ubicación restringida, nunca los incorpore a un control de versiones, y deje que keytool le solicite la contraseña en lugar de pasar -storepass en la línea de comandos, donde quedaría en el historial de su shell.
Ahorre un 10% en certificados SSL al realizar su pedido hoy mismo.
Emisión rápida, cifrado potente, 99,99% de confianza del navegador, asistencia dedicada y garantía de devolución del dinero en 25 días. Código del cupón: SAVE10

