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.

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!


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

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

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

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.


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.