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

96

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, defino o período de validade do certificado da CA raiz para 10 anos. Desde então, assinei muitos certificados para túneis OpenVPN, sites e servidores de e-mail, todos com também um período de validade de 10 anos (isso pode estar errado, mas eu não sabia melhor na época).

Encontrei muitos guias sobre a configuração de uma autoridade de certificação, mas poucas informações sobre seu gerenciamento e, em particular, sobre o que deve ser feito quando o certificado da autoridade de certificação raiz expirar, o que acontecerá em 2014. Portanto, tenho o seguinte questões:

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

A situação é um pouco mais complicada pelo fato de que meu único acesso a alguns dos clientes é por meio de um túnel OpenVPN que usa um certificado assinado pelo certificado de CA atual; portanto, se eu precisar substituir todos os certificados do cliente, precisarei copiar os novos arquivos para o cliente, reinicie o túnel, cruze meus dedos e espero que apareça depois.

Remy Blank
fonte

Respostas:

142

Manter a mesma chave privada na sua CA raiz permite que todos os certificados continuem a validar com êxito na nova raiz; tudo o que você precisa é 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, assinados 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 a partir dele:

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

Assine o certificado filho:

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

Tudo pronto, relacionamento de certificado normal. Vamos verificar a confiança:

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

Ok, então, 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 que? 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.

Inicie 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 VirtualHostescuta no 443 - lembre-se, o newroot.pemcertificado raiz nem existia quando cert.pemfoi 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 da MS? Primeiro é preciso confiar na raiz, depois tudo é bom, com o número de série da nova raiz:

newroot

E ainda deveríamos estar trabalhando com a raiz antiga também. Alterne a configuração do Apache:

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

Faça uma reinicialização completa no Apache, uma recarga não mudará as informações corretamente.

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

E, com o navegador da API de criptografia MS, o Apache apresenta a raiz antiga, mas a nova raiz ainda está no armazenamento raiz confiável do computador. Ele o encontrará e validará automaticamente em relação à raiz (nova) confiável, apesar do Apache apresentar uma cadeia diferente (a raiz antiga). Depois de extrair a nova raiz de raízes confiáveis ​​e adicionar o certificado raiz original, tudo está bem:

oldroot


Então é isso! Mantenha a mesma chave privada ao renovar, troque a nova raiz confiável e ela praticamente funciona . Boa sorte!

Shane Madden
fonte
2
De qualquer forma, qual é o objetivo de criar um novo certificado raiz se você apenas reutilizar a mesma chave privada? Se você continuar fazendo isso repetidamente, qual é o objetivo de ter uma data de validade para o certificado? Eu pensei que a expiração raiz fosse usada para forçar os administradores a criar uma chave privada mais nova (provavelmente mais forte) que é mais segura contra as máquinas cada vez mais avançadas que tentam quebrar as chaves. Uma chave de 40 bits feito há 20 anos não é seguro o suficiente para
jvhashe
2
@jvhashe Se o certificado raiz não for mais criptograficamente forte o suficiente, você deverá se livrar dele, independentemente da data de validade. Se você está gerando sua própria raiz, não há nada que o impeça de defini-la para expirar há centenas de anos, quando você não estará mais no planeta. A expiração é pouco relevante em um certificado raiz - e para um certificado filho, a expiração também não é sobre força criptográfica (pergunte às autoridades de certificação que estão se preparando para revogar todos os certificados de 1024 bits em outubro) - veja aqui para obter mais informações.
Shane Madden
3
Além do exposto, descobri que o número de série precisa ser o mesmo para este método funcionar.
Scott Presnell
2
-set_serial 01- WTF ??? VOCÊ NÃO PODE REUTILIZAR NÚMEROS DE SÉRIE . Você consultou a RFC 4158, Infraestrutura de Chave Pública da Internet X.509: Construção de Caminho de Certificação ? Ou você está apenas inventando as coisas? Você não tem idéia dos problemas que está causando nos agentes do usuário quando eles iniciam a criação do caminho.
1
@jww Você leu a resposta? Isso é apenas uma demonstração do fato de que a criptografia funciona. Esse comando está literalmente gerando apenas um certificado de teste que podemos verificar posteriormente, para testar o relacionamento entre o antigo e o novo certificado raiz. Se alguém estiver usando esses comandos diretamente, certamente espero que algo quebre, e eles percebem que precisam prestar atenção ao contexto de algo antes de executá-lo cegamente (ou fugir do controle sobre se 01é uma série aceitável em laboratório).
Shane Madden
14

Percebi que extensões de CA podem estar ausentes no certificado renovado da chave de CA original. Isso funcionou de maneira mais apropriada para mim (ele cria um ./renewedselfsignedca.conf em que as extensões da CA v3 são definidas e ca.key e ca.crt são considerados a chave e o certificado da CA original):

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
fonte
2
Esta foi uma adição extremamente útil. A resposta realmente válida não resulta em um certificado suficientemente compatível para mim se você tiver configurações arbitrárias na sua raiz original ca.
Theuni
1
Destacado, muito útil. Outra adição: como Scott Presnell nos comentários à resposta aceita, eu também tive que especificar manualmente o número de série hexadecimal do certificado renovado para que ele correspondesse ao antigo. Isso significava adicionar -set_serial 0xdeadbeefabba(não o real serial no :)) ao último comando x509. Somente então meus certificados de cliente foram verificados com êxito em relação ao certificado de CA renovado.
JK Laiho
Este método é mais fácil, pois mantém as mesmas informações que o certificado anterior.
Lepe
Eu criei um script para esta solução mais -set_serial - ver a minha resposta
Wolfgang Fahl
Essa resposta me salvou muito trabalho, depois de passar quase um dia em uma questão que exigia isso, eu estava prestes a desistir, eu tiro meu chapéu para você por isso!
Onitlikesonic
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 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
ggrandes
fonte
1

@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
Wolfgang Fahl
fonte
0

Quando o seu certificado raiz expirar, os certificados que você assinou com ele. Você precisará gerar um novo certificado raiz e assinar novos certificados com ele. Se você não deseja repetir o processo a cada poucos anos, a única opção real é estender a data válida no certificado raiz em algo como dez ou vinte anos: a raiz que eu criei para meu próprio uso estabeleci 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 a antiga expirar, para que você tenha tempo de mudar sem ficar contra a parede do tempo, se algo der errado. Dessa forma, você sempre pode voltar temporariamente para os documentos antigos até resolver seus problemas iniciais com o novo.

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

Snowhare
fonte
Esta resposta parece sugerir que é possível renovar um certificado raiz, reutilizando sua chave. Mas suspeito que isso não seja diferente de começar do zero, pois o novo certificado terá uma assinatura diferente e, portanto, não validará certificados de clientes existentes.
Remy Blank
sim, você pode estender prazo de validade ... e é menos trabalho do que recriar tudo PKI, certificados de cliente, e retrust nova raiz ...
ggrandes
A parte sobre a emissão de novos certificados de entidade final não é necessariamente verdadeira. Depende de como o AKID (Authority Key Identifier) ​​é representado nas autoridades de certificação subordinadas e nos certificados de entidade final. Se o AKID for baseado em {Nome Distinto, Número de Série} , a continuidade será alcançada. Consulte também RFC 4518, Infra-estrutura de Chave Pública da Internet X.509: Construção do Caminho de Certificação .
0

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

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

A última versão do OpenSSL disponível para o Debian 6 traz esse problema. Todos os certificados criados após 23.01.2018 produzem Validade: por 1901 ano!

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

Manuel
fonte