Reemitindo a CA raiz autoassinada sem invalidar os certificados assinados por ela

12

Criei uma Autoridade de Certificação raiz autoassinada para alguns serviços internos em nossa empresa, que eu mesmo configurei (principalmente em HTTPS). Em seguida, criei certificados para esses serviços, assinados com essa CA.

Agora, quero adicionar uma extensão x509 (ponto de distribuição da CRL) à autoridade de certificação raiz sem invalidar os certificados de servidor existentes emitidos por essa autoridade de certificação. Isso é possível?

Minha intuição é "sim" porque, pelo que entendi, o acesso à chave privada correspondente é necessário e suficiente para "autoridade total" sobre a identidade do certificado. Ou seja, a menos que haja algum tipo de nonce incorporado junto com a chave pública no certificado quando ele é gerado (provável).

Ainda sou bastante novo no gerenciamento de certificados SSL, mas acho que entendo o básico da cadeia de confiança padrão. Também me sinto confortável com o uso básico de outras criptografia PKI: gerencio chaves SSH e uso o GPG para assinatura e criptografia. Estudei Ciência da Computação, apesar de ser apenas um praticante autodidata de criptografia.

Eu nunca fiz um CSR para o IIRC original (acho que foi a saída direta de openssl req -new -x509). Ainda tenho a chave privada da CA original, é claro, e usando-a pude "reverter" o certificado original em uma Solicitação de assinatura de certificado: openssl x509 -x509toreq -in MyCA.pem -out MyCA.csr -signkey private/MyCA.key

Eu esperava que isso "extraísse" efetivamente o nonce mencionado acima e me permitisse recriar o certificado, mas desta vez com um crlDistributionPointscampo e, consequentemente, todos os certificados assinados com a CA original ainda validariam essa nova CA, com exceção que os clientes recuperariam meu arquivo CRL (atualmente vazio) do URL HTTP designado no campo.

Então eu fiz um arquivo de configuração de extensão ext.conf:

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

E eu gerei a nova versão da CA raiz a partir do CSR:

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

Agora, quando vejo o certificado com openssl x509 -text -in MyNewCA.pem | less

Eu posso ver a parte da extensão da 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`

Mas ai! Meus certificados assinados anteriormente não são mais validados com relação 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, estou procurando mais informações sobre como os certificados funcionam e por que. Mas também gostaria de ter uma solução para o problema que leva a este, então aqui estão algumas informações básicas.

Como entrei nessa bagunça: o HTTPS para serviços internos funciona muito bem quando minha CA é instalada por meio do RMB do Explorer → Instalar a GUI do certificado no Windows, ou /usr/local/share/ca-certificatesseguida pelo update-ca-certificatesDebian e Ubuntu. Mas recentemente deparei com uma exceção: Git no Windows, especificamente se instalado para usar o Windows Secure Channel como back-end SSL. Aparentemente, por padrão, insiste que deve haver um campo CRL nos certificados SSL.

Então, acho que é realmente um problema do Windows Secure Channel porque a mensagem de erro em que continuo sendo exibida parece inteiramente específica da 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.

Se eu instalar o Git com OpenSSL e concatenar manualmente minha CA no arquivo apontado por git.http.sslcainfo, ele funcionará, mas temo que meus usuários estejam inclinados a não verificar a identidade SSL se acharem que esse processo é mais trabalhoso do que clicando na GUI "fácil" do instalador de certificados do Windows.

AngerySysadmin
fonte
1
Somente a chave pública e o Assunto tornam um certificado exclusivo. Portanto, se você também não alterar, poderá assinar novamente o seu certificado enquanto altera todos os outros campos e extensões do conteúdo do seu coração.
garethTheRed
@garethTheRed ah, isso faz sentido. Não tenho certeza de como fazer isso; você poderia elaborar ou postar uma resposta com mais detalhes? Eu esperava que -x509toreqisso recuperasse todas as informações exclusivas da CA raiz existente, mas isso não ocorre ou há algo errado com meu processo a partir daí.
AngerySysadmin
1
req -new -x509e x509 -req -signkeyambos padronizam a série do certificado autoassinado como um número aleatório (embora isso possa ser substituído) efetivamente um nonce. Se o seu certificado filho (ou qualquer um deles) contiver AuthorityKeyIdentifier usando a opção 'issuer + serial' (em vez de ou além da opção 'keyid'), esse será o caso se você tiver usado cao arquivo de configuração padrão upstream, precisa criar a nova raiz com a mesma serial que a antiga; use -set_serial. ...
dave_thompson_085
... Mas alguns sw podem ficar descontentes se você tentar importar um novo certificado com o mesmo nome e serial que um já existente; pode ser necessário limpar o antigo primeiro.
Dave_thompson_085
1
Near-cross-dupe security.stackexchange.com/questions/17331/... PS: Eu acho que é possível obter o Windows para manualmente cache a CRL para uma CA, caso em que a falta de CRLDP talvez não importa, mas o quão inconveniente que seria Eu não sei.
Dave_thompson_085

Respostas:

6

Dois certificados são considerados iguais, desde que o Nome do Assunto e a Chave Pública dos certificados correspondam.

Portanto, tudo o que você precisa fazer é reutilizar as chaves e garantir que o Nome do Assunto no novo certificado seja o mesmo que o antigo. Depois disso, você pode alterar qualquer um dos outros campos e / ou extensões e o certificado resultante será considerado o mesmo.

Por exemplo, crie seu arquivo de configuração do 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

e salve como por exemplo rootca.cnf. Verifique se os elementos do [req_distinguished_name]são idênticos aos do certificado original da CA raiz (esta é a parte idêntica do nome do assunto).

Em seguida, execute:

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

onde rootca.keyé a chave privada usada no certificado original (essa é a parte idêntica da chave pública / privada).

Isso cria MyNewCA.pem, com o qual você pode verificar:

$ 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 novo certificado no lugar do original.

Você pode alterar outros campos e extensões, como o período de validade do certificado, mas lembre-se de que você realmente não deve ter nenhuma restrição (exceto basicConstraints = critical,CA:true) no certificado de CA raiz.


Após uma análise mais aprofundada, o problema pode estar relacionado ao fato de que o certificado da CA raiz substituta não possui basicConstraintas keyUsageextensões e possivelmente as extensões. Pode valer a pena tentar adicionar essas duas extensões à sua ext.confprimeira e testar o novo certificado de CA raiz resultante usando o -x509toreqmétodo que você postou.

garethTheRed
fonte
Obrigado pela resposta abrangente, ele realmente me ajudou a entender melhor as coisas. Com isso e com os comentários de @ dave_thompson_085, eu consegui regenerar minha autoridade de certificação de uma maneira que não invalida os certificados de filhos. Havia algumas coisas erradas na minha tentativa original (eu provavelmente deveria postar uma resposta com mais detalhes?) Também obrigado por esse ponto óbvio em retrospecto, mas importante, de que "Nome do sujeito" é um campo composto por esses campos específicos. De alguma forma, duvido que alguém poste uma resposta, por isso estou aceitando esta.
AngerySysadmin