Saltar al contenido

Keytool crea un certificado autofirmado de confianza

Ya no tienes que investigar más en otras páginas porque estás al lugar adecuado, contamos con la solución que buscas y sin liarte.

Solución:

Debería “establecer confianza” entre su servidor y el cliente (supongo que solo necesita realizar la autenticación del lado del servidor). Esto se debe a que utiliza certificados autofirmados. Eso implica importar el certificado de su servidor al almacén de confianza del cliente:

En el lado del servidor:

keytool -keystore  -alias  -export -file .cert

Copie el archivo .cert en el lado del cliente y luego:

keytool -keystore  -alias  -import -file .cert

No puede compartir el almacén de claves entre el cliente y el servidor, porque el almacén de claves contiene el key. Al autenticarse, el cliente omite los certificados con privados keys. Como se dijo anteriormente, debe implementar un almacén de confianza en el lado del cliente.

Los certificados de un almacén de claves no se comportan de la misma manera, dependiendo de cómo los generó o importó.

El tipo de entrada de un certificado importado (visto al enumerar detalladamente todo el almacén de claves con -list -v) es “trustCertEntry”. El tipo de entrada de un certificado generado es “PrivateKeyEntry”. Cuando exporta un certificado, solo exporta su público keyy una referencia opcional a su emisor.

Parece que necesita exportar el certificado autofirmado en su almacén de claves como un certificado de confianza en su almacén de confianza (los nombres tienen sentido aquí).

No haría eso, porque las implementaciones de SSL / TLS probablemente no lo admitan. Desde una perspectiva del mundo real, es como implementar el secreto privado en última instancia. key de Verisign en algún oscuro Servidor web para firmar páginas casuales, mientras que el único propósito de este privado key es permanecer en una caja fuerte y firmar otros certificados. Los implementadores de SSL / TLS probablemente no contaminen su código con tal caso de uso y, de todos modos, la extensión del certificado “KeyUsage” puede restringir el uso de un certificado a la firma, evitando el cifrado.

Por eso sugiero reconstruir una cadena de certificados para su prueba.

La documentación de keytool contiene una parte interesante sobre la creación de una cadena (-gencert comando) pero es un ejemplo muy esquelético que no cubre la relación almacén de claves-almacén de confianza. Lo he mejorado para simular una autoridad de certificación de terceros.

Una tienda temporal their-keystore.jks representa una autoridad emisora ​​de certificados. Lo alimento con una cadena de certificados de ca2 -> ca1 -> ca con ca siendo considerado como un certificado raíz. La cadena aparece con cada certificado no raíz (a saber ca1 y ca2) haciendo referencia a su emisor como Certificate[2]. Tenga en cuenta que cada certificado es “PrivateKeyEntry”.

Entonces le doy de comer al my-keystore.jks con esos certificados en orden: ca, ca1, ca2. Yo importo ca con el -trustcacerts opción que significa que se convierte en un certificado raíz. En my-keystore.jks cada certificado importado ahora es “trustCertEntry”, lo que significa que solo existe el público key. La relación de emisión solo aparece en el campo “Emisor”, pero está bien porque la relación de confianza importaba más en el momento de la importación.

En este punto my-keystore.jks simula un entorno que contiene algunos certificados de confianza, como un JRE nuevo. los their-keystore.jks simula a los propietarios de esos certificados, que tienen el poder de firmar solicitudes de certificados.

Yo también: creo un certificado autofirmado e1 en my-keystore.jks, consígalo firmado por ca2 (mediante their-keystore.jks) e importe el resultado firmado de nuevo en my-keystore.jks. e1 sigue siendo una “PrivateKeyEntry” (porque es privada key permanece en my-keystore.jks) pero ahora he construido la siguiente cadena: e1 -> ca2 -> ca1. Parece que ca1 -> ca está implícito con ca ser una autoridad de certificación.

Para construir el almacén de confianza, solo importo certificados ca, ca1 y ca2 de la misma manera que lo hice por my-keystore.jks. Tenga en cuenta que no importo e1, ya que espero que el cliente SSL / TLS lo valide contra ca2.

Creo que esto se acerca bastante a cómo funcionan las cosas en el mundo real. Lo bueno aquí es que tiene control total sobre los certificados y no depende de los cacerts de JRE.

Aquí está el código que pone en práctica lo que digo. Parece funcionar con Jetty (cliente y servidor) siempre que deshabilite la lista de revocación de certificados (un tema que queda para otro día).

#!/bin/bash

rm  their-keystore.jks 2> /dev/null
rm  my-keystore.jks    2> /dev/null
rm  my-truststore.jks  2> /dev/null

echo "===================================================="
echo "Creating fake third-party chain ca2 -> ca1 -> ca ..."
echo "===================================================="

keytool -genkeypair -alias ca  -dname cn=ca                           
  -validity 10000 -keyalg RSA -keysize 2048                           
  -ext BasicConstraints:critical=ca:true,pathlen:10000                
  -keystore their-keystore.jks -keypass Keypass -storepass Storepass

keytool -genkeypair -alias ca1 -dname cn=ca1                          
  -validity 10000 -keyalg RSA -keysize 2048                           
  -keystore their-keystore.jks -keypass Keypass -storepass Storepass

keytool -genkeypair -alias ca2 -dname cn=ca2                          
  -validity 10000 -keyalg RSA -keysize 2048                           
  -keystore their-keystore.jks -keypass Keypass -storepass Storepass


  keytool -certreq -alias ca1                                            
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass   
| keytool -gencert -alias ca                                             
    -ext KeyUsage:critical=keyCertSign                                   
    -ext SubjectAlternativeName=dns:ca1                                  
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass   
| keytool -importcert -alias ca1                                         
    -keystore   their-keystore.jks -keypass Keypass -storepass Storepass

#echo "Debug exit" ; exit 0

  keytool -certreq -alias ca2                                           
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -gencert -alias ca1                                           
    -ext KeyUsage:critical=keyCertSign                                  
    -ext SubjectAlternativeName=dns:ca2                                 
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -importcert -alias ca2                                        
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass

keytool -list -v -storepass Storepass -keystore their-keystore.jks


echo  "===================================================================="
echo  "Fake third-party chain generated. Now generating my-keystore.jks ..."
echo  "===================================================================="
read -p "Press a key to continue."

# Import authority's certificate chain

  keytool -exportcert -alias ca                                         
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -importcert -trustcacerts -noprompt -alias ca                 
    -keystore  my-keystore.jks -keypass Keypass -storepass Storepass

  keytool -exportcert -alias ca1                                        
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -importcert -noprompt -alias ca1                              
    -keystore  my-keystore.jks -keypass Keypass -storepass Storepass

  keytool -exportcert -alias ca2                                        
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -importcert -noprompt -alias ca2                              
    -keystore  my-keystore.jks -keypass Keypass -storepass Storepass

# Create our own certificate, the authority signs it.

keytool -genkeypair -alias e1  -dname cn=e1                        
  -validity 10000 -keyalg RSA -keysize 2048                        
  -keystore my-keystore.jks -keypass Keypass -storepass Storepass

  keytool -certreq -alias e1                                            
    -keystore my-keystore.jks -keypass Keypass -storepass Storepass     
| keytool -gencert -alias ca2                                           
    -ext SubjectAlternativeName=dns:localhost                           
    -ext KeyUsage:critical=keyEncipherment,digitalSignature             
    -ext ExtendedKeyUsage=serverAuth,clientAuth                         
    -keystore their-keystore.jks -keypass Keypass -storepass Storepass  
| keytool -importcert -alias e1                                         
    -keystore my-keystore.jks -keypass Keypass -storepass Storepass

keytool -list -v  -storepass Storepass -keystore  my-keystore.jks

echo "================================================="
echo "Keystore generated. Now generating truststore ..."
echo "================================================="
read -p "Press a key to continue."

  keytool -exportcert -alias ca                                        
    -keystore my-keystore.jks -keypass Keypass -storepass Storepass    
| keytool -importcert -trustcacerts -noprompt -alias ca                
    -keystore my-truststore.jks -keypass Keypass -storepass Storepass

  keytool -exportcert -alias ca1                                       
    -keystore my-keystore.jks -keypass Keypass -storepass Storepass    
| keytool -importcert -noprompt -alias ca1                             
    -keystore my-truststore.jks -keypass Keypass -storepass Storepass

  keytool -exportcert -alias ca2                                       
    -keystore my-keystore.jks -keypass Keypass -storepass Storepass    
| keytool -importcert -noprompt -alias ca2                             
    -keystore my-truststore.jks -keypass Keypass -storepass Storepass

keytool -list -v  -storepass Storepass -keystore  my-truststore.jks

rm  their-keystore.jks 2> /dev/null

No debes hacer eso. Un almacén de claves es estrictamente privado. Si se lo comunica a alguien, ha comprometido fatalmente la seguridad. No tiene sentido hacer este tipo de cosas solo para que funcione, porque no es funcionando, es solo una brecha de seguridad. Tiene que hacerlo bien: exportar desde el almacén de claves del servidor al almacén de confianza del cliente, y desde el almacén de claves del cliente, si lo hay, al almacén de claves del servidor.

Valoraciones y comentarios

Si te gustó nuestro trabajo, eres capaz de dejar un escrito acerca de qué te ha parecido esta crónica.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *