Autorización de certificación vencimiento y renovación del certificado raíz

96

En 2004, configuré una pequeña autoridad de certificación usando OpenSSL en Linux y los simples scripts de administración provistos con OpenVPN. De acuerdo con las guías que encontré en ese momento, establecí el período de validez del certificado de CA raíz en 10 años. Desde entonces, he firmado muchos certificados para túneles OpenVPN, sitios web y servidores de correo electrónico, todos los cuales también tienen un período de validez de 10 años (esto puede haber sido incorrecto, pero no lo sabía mejor en ese momento).

He encontrado muchas guías sobre la configuración de una CA, pero muy poca información sobre su administración y, en particular, sobre lo que debe hacerse cuando caduque el certificado de CA raíz, lo que sucederá en algún momento en 2014. Así que tengo lo siguiente preguntas:

  • ¿Los certificados que tienen un período de validez que se extiende después de la expiración del certificado de CA raíz dejarán de ser válidos tan pronto como expire este último o continuarán siendo válidos (porque se firmaron durante el período de validez del certificado de CA)?
  • ¿Qué operaciones son necesarias para renovar el certificado de CA raíz y garantizar una transición sin problemas después de su vencimiento?
    • ¿Puedo volver a firmar de alguna manera el certificado de CA raíz actual con un período de validez diferente y cargar el certificado recientemente firmado a los clientes para que los certificados de cliente sigan siendo válidos?
    • ¿O necesito reemplazar todos los certificados de cliente por otros nuevos firmados por un nuevo certificado de CA raíz?
  • ¿Cuándo se debe renovar el certificado de CA raíz? ¿Cerca del vencimiento, o un tiempo razonable antes del vencimiento?
  • Si la renovación del certificado de CA raíz se convierte en un trabajo importante, ¿qué puedo hacer mejor ahora para garantizar una transición más fluida en la próxima renovación (salvo establecer el período de validez en 100 años, por supuesto)?

La situación se complica un poco más por el hecho de que mi único acceso a algunos de los clientes es a través de un túnel OpenVPN que utiliza un certificado firmado por el certificado de CA actual, por lo que si tengo que reemplazar todos los certificados del cliente, tendré que copiar los nuevos archivos al cliente, reinicio el túnel, cruzo los dedos y espero que aparezca después.

Remy Blank
fuente

Respuestas:

142

Mantener la misma clave privada en su CA raíz permite que todos los certificados continúen validándose con éxito en la nueva raíz; todo lo que se requiere de ti es confiar en la nueva raíz.

La relación de firma del certificado se basa en una firma de la clave privada; mantener la misma clave privada (e, implícitamente, la misma clave pública) mientras se genera un nuevo certificado público, con un nuevo período de validez y cualquier otro atributo nuevo modificado según sea necesario, mantiene la relación de confianza en su lugar. Las CRL también pueden continuar del antiguo certificado al nuevo, ya que, como los certificados, están firmados por la clave privada.


Entonces, ¡verifiquemos!

Hacer una CA raíz:

openssl req -new -x509 -keyout root.key -out origroot.pem -days 3650 -nodes

Genere un certificado hijo a partir de él:

openssl genrsa -out cert.key 1024
openssl req -new -key cert.key -out cert.csr

Firme el certificado de niño:

openssl x509 -req -in cert.csr -CA origroot.pem -CAkey root.key -create_serial -out cert.pem
rm cert.csr

Todo listo allí, relación de certificado normal. Verifiquemos la confianza:

# openssl verify -CAfile origroot.pem -verbose cert.pem
cert.pem: OK

Ok, entonces, digamos que pasaron 10 años. Generemos un nuevo certificado público a partir de la misma clave privada raíz.

openssl req -new -key root.key -out newcsr.csr
openssl x509 -req -days 3650 -in newcsr.csr -signkey root.key -out newroot.pem
rm newcsr.csr

Y ... ¿funcionó?

# openssl verify -CAfile newroot.pem -verbose cert.pem
cert.pem: OK

¿Pero por qué? Son archivos diferentes, ¿verdad?

# sha1sum newroot.pem
62577e00309e5eacf210d0538cd79c3cdc834020  newroot.pem
# sha1sum origroot.pem
c1d65a6cdfa6fc0e0a800be5edd3ab3b603e1899  origroot.pem

Sí, pero eso no significa que la nueva clave pública no coincida criptográficamente con la firma en el certificado. Diferentes números de serie, mismo módulo:

# openssl x509 -noout -text -in origroot.pem
        Serial Number:
            c0:67:16:c0:8a:6b:59:1d
...
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd:
                    3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25:
                    8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57:
                    1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d:
                    4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a:
                    9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23:
                    6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98:
                    1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10:
                    d7:a3:66:0a:45:bd:0e:cd:9d
# openssl x509 -noout -text -in newroot.pem
        Serial Number:
            9a:a4:7b:e9:2b:0e:2c:32
...
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:bd:56:b5:26:06:c1:f6:4c:f4:7c:14:2c:0d:dd:
                    3c:eb:8f:0a:c0:9d:d8:b4:8c:b5:d9:c7:87:4e:25:
                    8f:7c:92:4d:8f:b3:cc:e9:56:8d:db:f7:fd:d3:57:
                    1f:17:13:25:e7:3f:79:68:9f:b5:20:c9:ef:2f:3d:
                    4b:8d:23:fe:52:98:15:53:3a:91:e1:14:05:a7:7a:
                    9b:20:a9:b2:98:6e:67:36:04:dd:a6:cb:6c:3e:23:
                    6b:73:5b:f1:dd:9e:70:2b:f7:6e:bd:dc:d1:39:98:
                    1f:84:2a:ca:6c:ad:99:8a:fa:05:41:68:f8:e4:10:
                    d7:a3:66:0a:45:bd:0e:cd:9d

Vayamos un poco más allá para verificar que está funcionando en la validación de certificados del mundo real.

Encienda una instancia de Apache y probémosla (estructura del archivo debian, ajuste según sea necesario):

# cp cert.pem /etc/ssl/certs/
# cp origroot.pem /etc/ssl/certs/
# cp newroot.pem /etc/ssl/certs/
# cp cert.key /etc/ssl/private/

Estableceremos estas directivas en una VirtualHostescucha en 443: recuerde, el newroot.pemcertificado raíz ni siquiera existía cuando cert.pemse generó y firmó.

SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/newroot.pem

Veamos cómo lo ve openssl:

# openssl s_client -showcerts -CAfile newroot.pem -connect localhost:443

Certificate chain
 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
 1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
MIICHzCCAYgCCQCapHvpKw4sMjANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJB
...
-----END CERTIFICATE-----
(this should match the actual contents of newroot.pem)
...
Verify return code: 0 (ok)

Ok, ¿y qué tal un navegador que usa la API criptográfica de MS? Primero tengo que confiar en la raíz, luego todo está bien, con el número de serie de la nueva raíz:

newroot

Y, todavía deberíamos estar trabajando con la raíz antigua, también. Cambie la configuración de Apache:

SSLEngine on
SSLCertificateFile /etc/ssl/certs/cert.pem
SSLCertificateKeyFile /etc/ssl/private/cert.key
SSLCertificateChainFile /etc/ssl/certs/origroot.pem

Haga un reinicio completo en Apache, una recarga no cambiará los certificados correctamente.

# openssl s_client -showcerts -CAfile origroot.pem -connect localhost:443

Certificate chain
 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=server.lan
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
 1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=root
-----BEGIN CERTIFICATE-----
MIIC3jCCAkegAwIBAgIJAMBnFsCKa1kdMA0GCSqGSIb3DQEBBQUAMFQxCzAJBgNV
...
-----END CERTIFICATE-----
(this should match the actual contents of origroot.pem)
...
Verify return code: 0 (ok)

Y, con el navegador MS crypto API, Apache presenta la raíz anterior, pero la nueva raíz todavía está en el almacén raíz de confianza de la computadora. Lo encontrará automáticamente y validará el certificado contra la raíz de confianza (nueva), a pesar de que Apache presenta una cadena diferente (la raíz antigua). Después de quitar la nueva raíz de las raíces confiables y agregar el certificado raíz original, todo está bien:

raíz vieja


¡Eso es todo! Mantenga la misma clave privada cuando renueve, cambie la nueva raíz confiable y prácticamente todo funciona . ¡Buena suerte!

Shane Madden
fuente
2
De todos modos, ¿qué sentido tiene crear un nuevo certificado raíz si solo va a reutilizar la misma clave privada? Si sigue haciendo esto una y otra vez, ¿cuál es el punto de tener una fecha de vencimiento para el certificado? Pensé que la expiración de la raíz se usó para obligar a los administradores a crear una clave privada más nueva (probablemente más fuerte) que sea más segura contra las máquinas que avanzan constantemente tratando de romper las claves. Una clave de 40 bits hecha hace 20 años no es lo suficientemente segura para
jvhashe
2
@jvhashe Si el certificado raíz ya no es lo suficientemente fuerte criptográficamente, entonces debería deshacerse de él independientemente de su fecha de vencimiento. Si estás generando tu propia raíz, no hay nada que te impida configurarla para que caduque hace cientos de años cuando ya no estés en el planeta. La caducidad apenas es relevante en un certificado raíz, y para un certificado secundario, la caducidad tampoco se trata realmente de la fuerza criptográfica (solicite a las CA que se están preparando para revocar todos los certificados de 1024 bits en octubre). Consulte aquí para obtener más información.
Shane Madden
3
Además de lo anterior, descubrí que el número de serie debe ser el mismo para que este método funcione.
Scott Presnell
2
-set_serial 01- WTF ??? NO PUEDE REUTILIZAR LOS NÚMEROS DE SERIE . ¿Ha consultado incluso RFC 4158, Infraestructura de clave pública de Internet X.509: Creación de ruta de certificación ? ¿O simplemente lo estás inventando a medida que avanzas? No tiene idea de los problemas que está causando en los agentes de usuario cuando comienzan a crear rutas.
1
@jww ¿Leíste la respuesta? Eso es solo una demostración del hecho de que la criptografía funciona. Ese comando literalmente solo genera un certificado de prueba con el que podemos verificar más adelante, con el fin de probar la relación entre el certificado raíz antiguo y el nuevo. Si alguien está usando esos comandos directamente, ciertamente espero que algo se rompa, y se dan cuenta de que deben prestar atención al contexto de algo antes de ejecutarlo ciegamente (o salirse del control sobre si 01es una serie aceptable en un laboratorio).
Shane Madden
14

Me di cuenta de que podrían faltar extensiones de CA en el certificado renovado de la clave de CA original. Esto funcionó más adecuadamente para mí (crea un ./renewedselfsignedca.conf donde se definen las extensiones v3 CA, y se supone que ca.key y ca.crt son la clave y el certificado CA originales):

openssl x509 -x509toreq -in ca.crt -signkey ca.key -out renewedselfsignedca.csr
echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > renewedselfsignedca.conf
openssl x509 -req -days 1095 -in renewedselfsignedca.csr -signkey ca.key -out renewedselfsignedca.crt -extfile ./renewedselfsignedca.conf -extensions v3_ca
Bianconiglio
fuente
2
Esta ha sido una adición extremadamente útil. La respuesta realmente válida no resulta en un certificado suficientemente compatible para mí si tiene configuraciones arbitrarias en su raíz original ca.
Theuni
1
Secundado, muy útil. Otra adición: como Scott Presnell en los comentarios a la respuesta aceptada, también tuve que especificar manualmente el número de serie hexadecimal del certificado renovado para que coincidiera con el anterior. Esto significaba agregar -set_serial 0xdeadbeefabba(no el número de serie real :)) al último comando x509. Solo entonces mis certificados de cliente verificaron con éxito el certificado de CA renovado.
JK Laiho
Este método es más fácil ya que mantiene la misma información que el certificado anterior.
lepe
He creado un script para esta solución más -set_serial - mira mi respuesta
Wolfgang Fahl el
Esta respuesta me ahorró mucho trabajo, después de pasar casi un día en un problema que requería esto, estaba a punto de rendirme, ¡te doy mi sombrero por esto!
Onitlikesonic
2

Modo básico para extender el período válido de root (necesita el X.509 público y la clave privada asociada):

Genere la CSR a partir de X.509 pública y clave privada:

openssl x509 -x509toreq -in XXX.crt -signkey XXX.key -out XXX.csr

Vuelva a firmar la CSR con clave privada:

openssl x509 -in XXX.csr -out XXX.crt -signkey XXX.key -req -days 365
ggrandes
fuente
1

@Bianconiglio plus -set_serial funcionó para mí. Mi servidor es solo intranet, así que no me preocupo demasiado por los efectos secundarios y ahora tengo tiempo para trabajar en una solución "adecuada".

Usé el siguiente script configurable. Simplemente configure las variables CACRT, CAKEY y NEWCA.

# WF 2017-06-30
# https://serverfault.com/a/501513/162693
CACRT=SnakeOilCA.crt
CAKEY=SnakeOilCA.key
NEWCA=SnakeOilCA2017
serial=`openssl x509 -in $CACRT -serial -noout | cut -f2 -d=`
echo $serial
openssl x509 -x509toreq -in $CACRT -signkey $CAKEY -out $NEWCA.csr
echo -e "[ v3_ca ]\nbasicConstraints= CA:TRUE\nsubjectKeyIdentifier= hash\nauthorityKeyIdentifier= keyid:always,issuer:always\n" > $NEWCA.conf
openssl x509 -req -days 3650 -in $NEWCA.csr -set_serial 0x$serial -signkey $CAKEY -out $NEWCA.crt -extfile ./$NEWCA.conf -extensions v3_ca
openssl x509 -in $NEWCA.crt -enddate -serial -noout
Wolfgang Fahl
fuente
0

Cuando su certificado raíz caduca, también lo hacen los certificados que ha firmado con él. Tendrá que generar un nuevo certificado raíz y firmar nuevos certificados con él. Si no desea repetir el proceso cada pocos años, la única opción real es extender la fecha válida en el certificado raíz como diez o veinte años: la raíz que generé para mi propio uso la establecí veinte años.

No puede "renovar" un certificado raíz. Todo lo que puedes hacer es generar uno nuevo.

Genere una nueva raíz al menos uno o dos años antes de que expire la anterior para que tenga tiempo de cambiar sin estar en contra de un muro temporal si algo sale mal. De esa manera, siempre puede cambiar temporalmente a los certificados anteriores hasta que resuelva sus problemas iniciales con el nuevo.

En lo que respecta a los túneles de VPN, configuraría un par de servidores de banco de pruebas con los que experimentar para que comprenda exactamente lo que tiene que hacer antes de hacerlo con la máquina de un cliente.

Snowhare
fuente
Esta respuesta parece sugerir que es posible renovar un certificado raíz, reutilizando su clave. Pero sospecho que esto no es diferente de comenzar desde cero, ya que el nuevo certificado tendrá una firma diferente y, por lo tanto, no validará los certificados de cliente existentes.
Remy Blank
sí, puede extender el período válido ... y es menos trabajo que recrear todos los pki, certificados de cliente y recuperar la nueva raíz ...
ggrandes
La parte sobre la emisión de nuevos certificados de entidad final no es necesariamente cierta. Depende de cómo se representa el Identificador de clave de autoridad (AKID) en las CA subordinadas y los certificados de entidad final. Si el AKID se basa en {Nombre distinguido, Número de serie} , se logrará la continuidad. Consulte también RFC 4518, Infraestructura de clave pública de Internet X.509: Creación de ruta de certificación .
0

Hemos tenido el mismo problema, y ​​eso fue en nuestro caso porque el servidor Debian estaba desactualizado y openSSL tenía este problema:

https://en.wikipedia.org/wiki/Year_2038_problem

La última versión de OpenSSL disponible para Debian 6 trae este problema. Todos los certificados creados después del 23.01.2018 producen una Vality: ¡para 1901 años!

La solución es actualizar OpenSSL. Puede volver a crear los archivos de configuración (con los certificados) para los clientes.

Manuel
fuente