Expiração e renovação do certificado raiz da autoridade de certificação

88

Em 2004, configurei uma pequena autoridade de certificação usando o OpenSSL no Linux e os scripts de gerenciamento simples fornecidos com o OpenVPN. De acordo com os guias que encontrei na época, defini o período de validade do certificado de CA raiz para 10 anos. Desde então, tenho assinado muitos certificados para túneis, sites e servidores de e-mail do OpenVPN, todos com um período de validade de 10 anos (isso pode ter sido errado, mas eu não sabia disso na época).

Eu encontrei muitos guias sobre como configurar uma autoridade de certificação, mas apenas poucas informações sobre seu gerenciamento e, em particular, sobre o que deve ser feito quando o certificado da CA raiz expira, o que acontecerá em 2014. Então, tenho as seguintes perguntas:

  • Os certificados com um período de validade estendido após a expiração do certificado da CA raiz se tornarão inválidos assim que o último expirar, ou continuarão sendo válidos (porque foram assinados durante o período de validade do certificado de autoridade de certificação) ?
  • Quais operações são necessárias para renovar o certificado de CA raiz e garantir uma transição suave durante o seu vencimento?
    • Posso de alguma forma assinar novamente o certificado de CA raiz atual com um período de validade diferente e fazer o upload do certificado recém assinado para os clientes, de forma que os certificados de cliente permaneçam válidos?
    • Ou preciso substituir todos os certificados de cliente por novos certificados assinados por um novo certificado de CA raiz?
  • Quando o certificado CA raiz deve ser renovado? Perto da expiração, ou um tempo razoável antes da expiração?
  • Se a renovação do certificado de CA raiz se tornar uma parte importante do trabalho, o que posso fazer melhor agora para garantir uma transição mais suave na próxima renovação (menos definir o período de validade para 100 anos, é claro)?

A situação se torna um pouco mais complicada pelo fato de que meu único acesso a alguns dos clientes é através de um túnel OpenVPN que usa um certificado assinado pelo certificado de CA atual, então se eu tiver que substituir todos os certificados de cliente, preciso copiar os novos arquivos para o cliente, reiniciar o túnel, cruzar os dedos e esperar que apareça depois.

    
por Remy Blank 30.08.2011 / 08:34

6 respostas

126

Manter a mesma chave privada em sua autoridade de certificação raiz permite que todos os certificados continuem sendo validados com êxito na nova raiz; tudo o que é exigido de você é confiar na nova raiz.

O relacionamento de assinatura de certificado é baseado em uma assinatura da chave privada; manter a mesma chave privada (e, implicitamente, a mesma chave pública) ao gerar um novo certificado público, com um novo período de validade e quaisquer outros novos atributos alterados conforme necessário, mantém a relação de confiança em vigor. As CRLs também podem continuar do certificado antigo para o novo, como são, como certificados, assinadas pela chave privada.

Então, vamos verificar!

Crie uma autoridade de certificação raiz:

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

Gere um certificado filho dele:

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

Assinar o certificado filho:

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

Tudo definido lá, relação de certificado normal. Vamos verificar a confiança:

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

Ok, agora vamos dizer que 10 anos se passaram. Vamos gerar um novo certificado público a partir da mesma chave privada raiz.

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

E ... funcionou?

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

Mas ... por quê? Eles são arquivos diferentes, certo?

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

Sim, mas isso não significa que a nova chave pública não corresponda criptograficamente à assinatura no certificado. Números de série diferentes, mesmo 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

Vamos um pouco mais longe para verificar se está funcionando na validação de certificados do mundo real.

Abra uma instância do Apache, e vamos tentar (estrutura do arquivo debian, ajuste conforme necessário):

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

Definiremos essas diretivas em VirtualHost ouvindo em 443 - lembre-se de que o certificado raiz newroot.pem nem existia quando cert.pem foi gerado e assinado.

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

Vamos ver como o openssl o vê:

# 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, e que tal um navegador usando a API de criptografia do MS? Tenho que confiar na raiz, primeiro, tudo bem, com o novo número de série da raiz:

Eaindadevemostrabalharcomaraizantigatambém.MudeaconfiguraçãodoApache:

SSLEngineonSSLCertificateFile/etc/ssl/certs/cert.pemSSLCertificateKeyFile/etc/ssl/private/cert.keySSLCertificateChainFile/etc/ssl/certs/origroot.pem

FaçaumreiníciocompletonoApache,umrecarregamentonãomudaráoscertificadoscorretamente.

#openssls_client-showcerts-CAfileorigroot.pem-connectlocalhost:443Certificatechain0s:/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=server.lani:/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=root-----BEGINCERTIFICATE-----...-----ENDCERTIFICATE-----1s:/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=rooti:/C=AU/ST=Some-State/O=InternetWidgitsPtyLtd/CN=root-----BEGINCERTIFICATE-----MIIC3jCCAkegAwIBAgIJAMBnFsCKa1kdMA0GCSqGSIb3DQEBBQUAMFQxCzAJBgNV...-----ENDCERTIFICATE-----(thisshouldmatchtheactualcontentsoforigroot.pem)...Verifyreturncode:0(ok)

E,comonavegadordaAPIdecriptografiaMS,oApacheapresentaaraizantiga,masanovaraizaindaestánoarmazenamentoderaizconfiáveldocomputador.Eleiráencontrá-loautomaticamenteevalidarocertificadocontraaraizconfiável(nova),apesardoApacheapresentarumacadeiadiferente(araizantiga).Depoisderemoveranovaraizdasraízesconfiáveiseadicionarocertificadoraizoriginal,tudoestábem:

Então é isso! Mantenha a mesma chave privada quando você renovar, troque na nova raiz confiável e praticamente tudo simplesmente funciona . Boa sorte!

    
por 04.09.2011 / 18:40
13

Percebi que as extensões de CA podem estar ausentes no certificado renovado da chave da CA original. Isso funcionou mais apropriadamente para mim (cria um ./ renewedselfsignedca.conf onde as extensões da CA v3 são definidas e ca.key e ca.crt são assumidos como sendo a chave e o certificado originais da CA):

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
    
por 22.04.2013 / 10:31
2

Modo básico para estender o período válido de raiz (você precisa do X.509 público e da chave privada associada):

Gere o CSR a partir do X.509 público e da chave privada:

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

Assine novamente o CSR com chave privada:

openssl x509 -in XXX.csr -out XXX.crt -signkey XXX.key -req -days 365
    
por 22.01.2013 / 16:35
0

Quando o seu certificado raiz expira, o mesmo acontece com os certificados que você assinou com ele. Você terá que gerar um novo certificado raiz e assinar novos certificados com ele. Se você não quiser repetir o processo a cada poucos anos, a única opção real é estender a data válida no certificado raiz, algo como dez ou vinte anos: a raiz que eu gero para meu próprio uso eu estabeleço vinte anos.

Você não pode "renovar" um certificado raiz. Tudo o que você pode fazer é gerar um novo.

Gere uma nova raiz pelo menos um ano ou dois antes de sua antiga expirar, para que você tenha tempo de mudar sem estar contra um tempo se algo der errado. Dessa forma, você pode sempre alternar temporariamente para os antigos certificados até resolver seus problemas iniciais com o novo.

No que diz respeito aos túneis de VPN, eu configuraria alguns servidores de teste para experimentar, para que você entenda exatamente o que precisa fazer antes de fazer isso com a máquina de um cliente.

    
por 03.09.2011 / 23:59
0

@Bianconiglio plus -set_serial funcionou para mim. Meu servidor é apenas intranet, então não estou me preocupando muito com os efeitos colaterais e agora tenho tempo para trabalhar em uma solução "adequada".

Eu usei o seguinte script configurável. Basta definir as variáveis CACRT, CAKEY e 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
    
por 30.06.2017 / 17:33
0

Tivemos o mesmo problema, e isso ocorreu em nosso caso porque o servidor Debian estava desatualizado e o openSSL tinha esse problema:

link

A última versão do OpenSSL disponível para o Debian 6 traz este problema. Todos os certificados criados após 23.01.2018 produzem um Vality: para 1901 anos!

A solução é atualizar o OpenSSL. Você pode criar novamente os arquivos de configuração (com os certificados) para os clientes.

    
por 09.03.2018 / 10:38