Expiration et renouvellement du certificat racine de l'autorité de certification

96

En 2004, j'ai créé une petite autorité de certification utilisant OpenSSL sous Linux et les scripts de gestion simples fournis avec OpenVPN. Conformément aux guides que j'ai trouvés à l'époque, j'ai défini la période de validité du certificat d'autorité de certification racine à 10 ans. Depuis lors, j'ai signé de nombreux certificats pour les tunnels OpenVPN, les sites Web et les serveurs de messagerie, qui ont également une durée de validité de 10 ans (c'est peut-être faux, mais je ne savais pas mieux le faire à l'époque).

J'ai trouvé de nombreux guides sur la configuration d'une autorité de certification, mais très peu d'informations sur sa gestion, et en particulier sur ce qu'il faut faire à l'expiration du certificat de l'autorité de certification racine, ce qui se produira dans le courant de 2014. Nous avons donc les éléments suivants: des questions:

  • Les certificats dont la période de validité est prolongée après l'expiration du certificat racine de l'autorité de certification deviendront-ils invalides dès l'expiration de ce dernier ou resteront-ils valides (car ils ont été signés pendant la période de validité du certificat de l'autorité de certification)?
  • Quelles opérations sont nécessaires pour renouveler le certificat de l'autorité de certification racine et assurer une transition en douceur après son expiration?
    • Puis-je en quelque sorte signer à nouveau le certificat actuel de l'autorité de certification racine avec une période de validité différente et télécharger le certificat nouvellement signé sur les clients afin que les certificats clients restent valides?
    • Ou dois-je remplacer tous les certificats clients par de nouveaux signés par un nouveau certificat d'autorité de certification racine?
  • Quand le certificat de l'autorité de certification racine doit-il être renouvelé? Près de la date d'expiration ou un délai raisonnable avant la date d'expiration?
  • Si le renouvellement du certificat de l'autorité de certification racine devient un travail majeur, que puis-je faire de mieux pour assurer une transition plus en douceur lors du prochain renouvellement (à moins de fixer la période de validité à 100 ans, bien sûr)?

La situation est légèrement compliquée par le fait que mon seul accès à certains clients se fait via un tunnel OpenVPN qui utilise un certificat signé par le certificat actuel de l'autorité de certification. Par conséquent, si je dois remplacer tous les certificats de client, je devrai copier les nouveaux fichiers sur le client, redémarrez le tunnel, me croisent les doigts et espérons qu'il reviendra après.

Remy Blank
la source

Réponses:

142

Garder la même clé privée sur votre autorité de certification racine permet à tous les certificats de continuer à se valider avec succès sur la nouvelle racine; tout ce qui vous est demandé est de faire confiance à la nouvelle racine.

La relation de signature de certificat est basée sur une signature de la clé privée; conserver la même clé privée (et, implicitement, la même clé publique) tout en générant un nouveau certificat public, avec une nouvelle période de validité et tout autre nouvel attribut modifié en fonction des besoins, maintient la relation de confiance en place. Les listes de révocation de certificats peuvent également continuer de l'ancien au nouveau certificat, car elles sont, comme les certificats, signées par la clé privée.


Alors, vérifions!

Créer une autorité de certification racine:

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

Générez un certificat enfant à partir de celui-ci:

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

Signez le cert enfant:

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

Tout y est défini, relation de certificat normale. Vérifions la confiance:

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

Ok, alors, disons maintenant que 10 ans ont passé. Générons un nouveau certificat public à partir de la même clé privée racine.

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

Et .. cela a-t-il fonctionné?

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

Mais pourquoi? Ce sont des fichiers différents, non?

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

Oui, mais cela ne signifie pas que la nouvelle clé publique ne correspond pas de manière cryptographique à la signature du certificat. Différents numéros de série, même module:

# 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

Allons un peu plus loin pour vérifier que cela fonctionne dans la validation de certificats dans le monde réel.

Lancez une instance Apache et testons-la (structure de fichier debian, ajustez-la si nécessaire):

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

Nous allons définir ces directives sur une VirtualHostécoute sur 443 - rappelez-vous, le newroot.pemcertificat racine n'existait même pas quand il a cert.pemété généré et signé.

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

Voyons comment openssl le voit:

# 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, et qu'en est-il d'un navigateur utilisant l'API crypto de MS? Il faut d'abord faire confiance à la racine, puis tout va bien, avec le numéro de série de la nouvelle racine:

newroot

Et nous devrions également continuer à travailler avec l'ancienne racine. Basculez la configuration d'Apache autour de:

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

Faites un redémarrage complet sur Apache, un rechargement ne changera pas les certificats correctement.

# 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)

De plus, avec le navigateur de l'API de chiffrement MS, Apache présente l'ancienne racine, mais la nouvelle racine est toujours dans le magasin de racines de confiance de l'ordinateur. Il le trouvera automatiquement et validera le certificat par rapport à la (nouvelle) racine approuvée, bien qu'Apache présente une chaîne différente (l'ancienne racine). Après avoir retiré la nouvelle racine des racines approuvées et ajouté le certificat racine d'origine, tout va bien:

oldroot


Alors c'est tout! Conservez la même clé privée lors de votre renouvellement, remplacez-la par la nouvelle racine approuvée et tout fonctionne . Bonne chance!

Shane Madden
la source
2
Quoi qu'il en soit, quel est l'intérêt de créer un nouveau certificat racine si vous souhaitez simplement réutiliser la même clé privée? Si vous continuez à le faire encore et encore, alors à quoi sert-il d'avoir une date d'expiration pour le certificat? Je pensais que l’expiration de la racine était utilisée pour forcer les administrateurs à créer une clé privée plus récente (probablement la plus puissante) plus sécurisée contre les machines en constante évolution qui tentaient de casser les clés. Une clé de 40 bits fabriquée il y a 20 ans n'est pas assez sûre pour
jvhashe
2
@jvhashe Si le certificat racine n'est plus assez puissant sur le plan cryptographique, vous devriez vous en débarrasser quelle que soit sa date d'expiration. Si vous générez votre propre racine, rien ne vous empêche de la faire expirer des centaines d'années plus tard, lorsque vous ne serez plus sur la planète. L'expiration est à peine pertinente pour un certificat racine - et pour un certificat enfant, l'expiration ne concerne pas non plus réellement la force cryptographique (demandez aux autorités de certification qui se préparent de révoquer tous les certificats 1024 bits en octobre) - voir ici pour plus d'informations.
Shane Madden
3
En plus de ce qui précède, j'ai constaté que le numéro de série doit être identique pour que cette méthode fonctionne.
Scott Presnell
2
-set_serial 01- WTF ??? VOUS NE POUVEZ PAS RÉUTILISER LES NUMÉROS DE SÉRIE . Avez-vous même consulté RFC 4158, Infrastructure à clé publique Internet X.509: Création d'un chemin de certification ? Ou êtes-vous en train de inventer au fur et à mesure? Vous n'avez aucune idée des problèmes que vous rencontrez dans les agents utilisateurs lorsqu'ils commencent à créer un chemin.
1
@jww Avez-vous lu la réponse? C'est juste une démonstration du fait que la cryptographie fonctionne. Cette commande génère littéralement un certificat de test que nous pourrons vérifier par la suite, afin de tester la relation entre l'ancien et le nouveau certificat racine. Si quelqu'un est d' utiliser ces commandes directement, je l' espère certainement quelque chose se brise, et ils se rendent compte qu'ils ont besoin de prêter attention au contexte de quelque chose avant d' exécuter aveuglément (ou volant de la poignée de savoir si 01est une série acceptable dans un laboratoire).
Shane Madden
14

J'ai remarqué que des extensions de l'autorité de certification pouvaient manquer dans le certificat renouvelé de la clé de l'autorité de certification d'origine. Cela a mieux fonctionné pour moi (cela crée un fichier ./renewedselfsignedca.conf dans lequel les extensions v3 de l'autorité de certification sont définies, et ca.key et ca.crt sont supposés être la clé et le certificat de l'autorité de certification d'origine):

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
la source
2
Cela a été un ajout extrêmement utile. La réponse réellement valable ne donne pas un certificat suffisamment compatible pour moi si vous avez des paramètres arbitraires sur votre racine d'origine.
Theuni
1
Détaché, très utile. Autre ajout: comme Scott Presnell dans les commentaires de la réponse acceptée, je devais aussi spécifier manuellement le numéro de série hexadécimal du certificat renouvelé afin qu'il corresponde à l'ancien. Cela signifiait ajouter -set_serial 0xdeadbeefabba(pas le vrai numéro de série :)) à la dernière commande x509. Ce n’est qu’alors que mes certificats clients ont été vérifiés avec le certificat d’autorité de certification renouvelé.
JK Laiho
Cette méthode est plus facile car elle conserve les mêmes informations que le certificat précédent.
lepe
J'ai créé un script pour cette solution plus -set_serial - voir ma réponse
Wolfgang Fahl le
Cette réponse m'a épargné beaucoup de travail. Après avoir passé presque une journée sur une question qui l'exigeait, j'étais sur le point d'abandonner, je vous tire mon chapeau pour ça!
Onitlikesonic
2

Mode de base pour étendre la période de validité de la racine (vous avez besoin de la clé publique X.509 et de la clé privée associée):

Générez le CSR à partir de X.509 publique et de clé privée:

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

Re-signez le CSR avec la clé privée:

openssl x509 -in XXX.csr -out XXX.crt -signkey XXX.key -req -days 365
grandes
la source
1

@ Bianconiglio plus -set_serial a fonctionné pour moi. Mon serveur est uniquement intranet, donc je ne m'inquiète pas trop des effets secondaires, et j'ai maintenant le temps de travailler sur une solution "appropriée".

J'ai utilisé le script configurable suivant. Il suffit de définir les variables CACRT, CAKEY et 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
la source
0

Lorsque les certificats racine expirent, les certificats que vous avez signés le sont également. Vous devrez générer un nouveau certificat racine et signer de nouveaux certificats avec celui-ci. Si vous ne voulez pas répéter le processus toutes les quelques années, la seule option possible est de prolonger la date de validité du certificat racine de 10 à 20 ans: La racine que j'ai générée pour mon usage personnel est définie pour vingt ans.

Vous ne pouvez pas "renouveler" un certificat racine. Tout ce que vous pouvez faire, c'est en générer un nouveau.

Générez une nouvelle racine au moins un an ou deux avant l’expiration de votre ancienne racine afin que vous ayez le temps de changer sans vous opposer à un mur du temps si quelque chose ne va pas. De cette façon, vous pouvez toujours revenir temporairement aux anciens certificats jusqu'à ce que vos problèmes initiaux avec le nouveau soient résolus.

En ce qui concerne les tunnels VPN, je voudrais installer quelques serveurs de testbed afin que vous compreniez précisément ce que vous devez faire avant de le faire avec la machine d'un client.

Snowhare
la source
Cette réponse semble suggérer qu'il est possible de renouveler un certificat racine en réutilisant sa clé. Mais je suppose que cela n’est pas différent de partir de zéro, car le nouveau certificat aura une signature différente et ne validera donc pas les certificats de client existants.
Remy Blank
oui, vous pouvez prolonger la période de validité ... et représente moins de travail que de recréer tous les certificats de pki et de client, et récupérer la nouvelle racine ...
ggrandes
La partie relative à l'émission de nouveaux certificats d'entité finale n'est pas nécessairement vraie. Cela dépend de la façon dont l'identificateur de clé d'autorité (AKID) est représenté dans les autorités de certification subordonnées et les certificats d'entité finale. Si le AKID est basé sur {Nom distinctif, numéro de série} , la continuité sera alors atteinte. Voir également RFC 4518, Infrastructure de clé publique Internet X.509: Certification Path Building .
0

Nous avons eu le même problème, et c'était dans notre cas parce que le serveur Debian était à jour, et openSSL avait ce problème:

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

La dernière version d'OpenSSL disponible pour Debian 6 pose ce problème. Tous les certificats créés après le 23.01.2018 produisent une Vality: pour 1901!

La solution consiste à mettre à jour OpenSSL. Vous pouvez créer à nouveau les fichiers de configuration (avec les certificats) pour les clients.

Manuel
la source