Volver a emitir CA raíz autofirmada sin invalidar certificados firmados por ella

12

Creé una Autoridad de certificación raíz autofirmada para algunos servicios internos en nuestra empresa, que configuré yo mismo (principalmente servido a través de HTTPS). Luego creé certificados para esos servicios, firmados con esta CA.

Ahora quiero agregar una extensión x509 (punto de distribución CRL) a la CA raíz sin invalidar los certificados de servidor existentes emitidos por esta CA. es posible?

Mi instinto es "sí" porque, según tengo entendido, el acceso a la clave privada correspondiente es necesario y suficiente para una "plena autoridad" sobre la identidad del certificado. Es decir, a menos que haya algún tipo de nonce incorporado junto con la clave pública en el certificado cuando se genera (probablemente).

Todavía soy bastante nuevo en la administración de certificados SSL, pero (creo que) entiendo los conceptos básicos de la cadena de confianza estándar. También me siento cómodo con el uso básico de otras criptomonedas PKI: administro claves SSH y uso GPG para firmar y cifrar. Estudié Ciencias de la Computación, aunque solo soy un aficionado autodidacta en criptografía.

Nunca hice una CSR para el IIRC original (creo que fue la salida directa de openssl req -new -x509). Todavía tengo la clave privada de la CA original, por supuesto, y al usarla pude "revertir" el certificado original en una Solicitud de firma de certificado: openssl x509 -x509toreq -in MyCA.pem -out MyCA.csr -signkey private/MyCA.key

Esperaba que esto efectivamente "extrajera" el nonce mencionado anteriormente, y me permitiera volver a crear el certificado, pero esta vez con un crlDistributionPointscampo, y en consecuencia todos los certificados que se firmaron con la CA original aún se validarían contra esta nueva CA, con la excepción que los clientes recuperarían mi archivo CRL (actualmente vacío) de la URL HTTP designada en el campo.

Entonces hice un archivo de configuración de extensión ext.conf:

[ cert_ext ] 
subjectKeyIdentifier=hash
crlDistributionPoints=URI:http://security.mycompany.co.za/root.crl

Y generé la nueva versión de la CA raíz de la CSR:

openssl x509 -extfile ./ext.conf -extensions cert_ext -req -signkey private/MyCA.key -in MyCA.csr -out MyNewCA.pem

Ahora cuando veo el certificado con openssl x509 -text -in MyNewCA.pem | less

Puedo ver la parte de extensión de CRL:

X509v3 extensions:
    X509v3 Subject Key Identifier: 
        82:D0:01:03:49:FF:30:16:FA:DC:0A:1E:C1:8C:3D:66:A1:78:FF:F8
    X509v3 CRL Distribution Points: 

        Full Name:
          URI:http://security.mycompany.co.za/root.crl`

¡Pero Ay! Mis certificados firmados anteriormente ya no se validan con respecto a este:

openssl verify -verbose -CAfile MyCA.pem git.pem 
git.pem: OK

openssl verify -verbose -CAfile MyNewCA.pem git.pem 
git.pem: <redacted DN>
error 20 at 0 depth lookup:unable to get local issuer certificate

Principalmente estoy buscando más información sobre cómo funcionan los certificados y por qué. Pero también agradecería una solución al problema que condujo a este, así que aquí hay información de fondo también.

Cómo me metí en este lío: HTTPS para servicios internos funciona muy bien una vez que mi CA está instalada a través de Explorer RMB → Instalar GUI de certificado en Windows, o /usr/local/share/ca-certificatesseguido por update-ca-certificatesDebian y Ubuntu. Pero recientemente me encontré con una excepción: Git en Windows, específicamente si está instalado para usar Windows Secure Channel como back-end SSL. Que aparentemente por defecto insiste en que debe haber un campo CRL en los certificados SSL.

Así que supongo que es realmente un problema de Windows Secure Channel porque el mensaje de error con el que me encuentro parece completamente específico de Microsoft: fatal: unable to access 'https://[email protected]/gitblit/r/secret_project.git/': schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - The revocation function was unable to check revocation for the certificate.

Si instalo Git con OpenSSL y concateno manualmente mi CA en el archivo señalado por git.http.sslcainfo, entonces funciona, pero me temo que mis usuarios se verán inclinados a no verificar la identidad SSL si creen que este proceso es más difícil que haciendo clic en la GUI "fácil" del instalador de certificados de Windows.

AngerySysadmin
fuente
1
Solo la clave pública y el Asunto hacen que un certificado sea único. Por lo tanto, si tampoco cambia, debería poder volver a firmar su certificado mientras modifica todos los demás campos y extensiones al contenido de su corazón.
garethTheRed
@garethTheRed ah, eso tiene sentido. No estoy seguro de cómo hacer esto; ¿Podría elaborar o publicar una respuesta con más detalles? Esperaba que -x509toreqrecuperara toda la información única de la CA raíz existente, pero o no lo hace o hay algo mal con mi proceso desde allí.
AngerySysadmin
1
req -new -x509y x509 -req -signkeyambos predeterminan la serie del certificado autofirmado a un número aleatorio (aunque esto puede anularse) efectivamente un nonce. Si su certificado de hijo (o cualquiera de ellos) contiene AuthorityKeyIdentifier utilizando la opción 'emisor + serie' (en lugar de o además de la opción 'keyid'), que será el caso si lo usó cacon el archivo de configuración predeterminado ascendente, necesita crear la nueva raíz con la misma serie que la anterior; uso -set_serial. ...
dave_thompson_085
... Pero algunos sw pueden ser infelices si intenta importar un nuevo certificado con el mismo nombre y serie que uno existente; Puede que tenga que limpiar el viejo primero.
dave_thompson_085
1
Near-cross-dupe security.stackexchange.com/questions/17331/… PD: Creo que es posible hacer que Windows almacene en caché manualmente la CRL para una CA, en cuyo caso la falta de CRLDP podría no importar, pero qué inconveniente sería No lo sé.
dave_thompson_085

Respuestas:

6

Dos certificados se consideran iguales siempre que coincidan el Nombre del sujeto y la Clave pública de los certificados.

Por lo tanto, todo lo que necesita hacer es reutilizar las claves y asegurarse de que el Nombre del sujeto en el nuevo certificado sea el mismo que el anterior. Después de eso, puede cambiar cualquiera de los otros campos y / o extensiones y el certificado resultante se considerará igual.

Por ejemplo, cree su archivo de configuración de OpenSSL:

[ req ]

prompt             = no
string_mask        = default
distinguished_name = x509_distinguished_name
x509_extensions     = x509_ext

[ x509_distinguished_name ]

# Note that the following are in 'reverse order' to what you'd expect to see.
# Adjust for your setup:

countryName = za
organizationName = My Company
organizationalUnitName = Security
commonName = My Root CA

[ x509_ext ]

basicConstraints = critical,CA:true
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
crlDistributionPoints = URI:http://security.mycompany.co.za/root.crl

y guardarlo como por ejemplo rootca.cnf. Asegúrese de que los elementos [req_distinguished_name]son idénticos a los de su certificado original de CA raíz (esta es la parte idéntica del nombre del sujeto).

A continuación, ejecute:

openssl req -new -x509 -key rootca.key -out MyNewCA.pem -config rootca.cnf

donde rootca.keyestá la clave privada utilizada en el certificado original (esta es la parte idéntica de clave pública / privada).

Esto crea MyNewCA.pem, que puedes consultar con:

$ openssl x509 -noout -text -in MyNewCA.pem

Certificate:
Data:
    Version: 3 (0x2)
    Serial Number: 17564687072266118846 (0xf3c24dd49d5166be)
Signature Algorithm: sha256WithRSAEncryption
    Issuer: C=za, O=My Company, OU=Security, CN=My Root CA
    Validity
        Not Before: Jul 15 05:05:54 2017 GMT
        Not After : Aug 14 05:05:54 2017 GMT
    Subject: C=za, O=My Company, OU=Security, CN=My Root CA
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:c8:3d:32:8a:56:31:f6:27:1a:ce:9e:b2:1d:fb:
                ce:9f:ce:5b:42:25:aa:fe:8b:f4:34:32:ac:b3:02:
                50:71:f8:c3:43:0c:c7:2c:9f:fe:48:1b:c6:c0:e7:
                d6:44:a9:e7:d7:a0:7e:58:f4:b6:38:61:7e:d0:af:
                0f:56:21:e7:49:7a:66:13:f5:7a:fe:3d:ab:65:f8:
                01:eb:52:a7:3b:ae:a0:cf:50:57:b9:e0:09:0b:1f:
                90:14:fb:18:56:1d:57:99:a9:76:a2:63:d1:c2:d3:
                a3:f4:3a:ff:91:0d:ee:8d:44:13:58:00:09:93:da:
                e8:6a:fd:64:5f:c3:42:8e:2a:49:6e:0d:73:b7:b9:
                d4:6c:c6:ce:30:c5:82:24:a5:00:37:17:a0:1d:f1:
                c9:e9:e3:18:48:22:4f:33:96:a7:3c:a9:31:f1:3f:
                14:40:6a:74:e8:78:82:45:04:d4:4b:56:0b:cd:be:
                48:8d:03:fb:39:70:0b:91:99:70:06:bd:5e:8b:f2:
                d1:f4:6f:fc:ce:e7:f8:3c:0a:20:ea:35:b8:5f:2f:
                ee:8d:ff:d3:93:85:6b:fb:71:db:1b:e6:e9:1d:a7:
                f8:e4:ae:f4:71:fe:35:a7:89:24:af:69:a4:34:3b:
                14:66:05:02:5e:2a:1d:ac:e0:d2:48:6c:13:4e:75:
                58:93
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Basic Constraints: critical
            CA:TRUE
        X509v3 Key Usage: critical
            Certificate Sign, CRL Sign
        X509v3 Subject Key Identifier: 
            3B:45:93:3A:2A:BC:39:29:36:13:6C:BD:B6:B4:31:C7:E7:BB:32:73
        X509v3 CRL Distribution Points: 

            Full Name:
              URI:http://security.mycompany.co.za/root.crl

Signature Algorithm: sha256WithRSAEncryption
     4d:96:d4:03:4f:e3:7c:26:be:59:f8:23:87:60:f7:4c:d3:a1:
     1c:77:a1:14:e3:e7:da:c8:2a:a3:1b:06:2a:4d:55:1c:83:26:
     73:46:0d:8a:e4:b7:d1:1e:38:cc:78:90:00:01:b3:8e:f9:3c:
     62:be:04:09:90:4e:22:87:b1:aa:bd:f9:73:bd:a7:76:ad:d5:
     ae:2d:7a:1c:1e:1a:67:c8:57:4c:f9:6d:8b:62:d6:e5:ea:e0:
     40:5c:12:28:7e:ea:f0:0c:d6:cd:f4:1d:d5:56:09:ad:43:b4:
     eb:8c:68:ce:56:a2:a8:ae:a4:d5:35:bb:58:b8:ed:82:82:b5:
     ef:cb:e2:6d:76:61:ed:ee:a5:1f:68:95:07:ed:5b:f0:65:92:
     d2:dc:1d:c6:fa:7f:e0:c9:38:c2:c6:6f:03:38:e7:3a:b0:24:
     06:e0:bc:07:dd:e7:a0:dc:74:09:e5:37:7b:66:e1:6f:47:4c:
     71:ff:02:48:7f:d4:4f:ce:cb:91:e9:ee:cd:b6:f1:0a:03:19:
     3e:19:05:7d:8f:48:e7:f1:cc:07:37:3d:91:3c:6f:54:71:3c:
     a2:6c:55:c3:03:c1:7f:eb:9e:70:f1:8f:a1:fb:62:33:8b:86:
     2c:79:bc:76:e2:01:9a:68:df:af:40:a1:b2:9c:f6:a1:e1:6e:
     2a:dd:1a:d6

Use este nuevo certificado en lugar del original.

Puede cambiar otros campos y extensiones, como el período de validez del certificado, pero tenga en cuenta que realmente no debería tener ninguna restricción (aparte de basicConstraints = critical,CA:true) en el certificado de CA raíz.


Después de una consideración adicional, su problema puede deberse simplemente al hecho de que su certificado de CA raíz de reemplazo no tiene la basicConstrainty posiblemente las keyUsageextensiones. Puede valer la pena intentar agregar esas dos extensiones a su ext.confprimera y probar el nuevo certificado resultante de CA raíz utilizando el -x509toreqmétodo que publicó.

garethTheRed
fuente
Gracias por la respuesta integral, realmente me ha ayudado a comprender mejor las cosas. Con esto y los comentarios de @ dave_thompson_085, he logrado regenerar mi CA de una manera que no invalida los certificados de niños. Hubo algunos problemas con mi intento original (¿probablemente debería publicar una respuesta con más detalles?) También gracias por ese punto obvio en retrospectiva pero importante de que "Nombre del sujeto" es un campo compuesto por esos campos en particular. De alguna manera dudo que alguien más publique una respuesta, así que estoy aceptando esta.
AngerySysadmin