Autoridade Certificadora (Certificate Authority – CA) Pessoal/Empresarial com o OpenSSL: parte 1

Se você administra uma rede de servidores com acesso externo como por exemplo servidores web, servidores de bancos de dados, servidores de diretório, servidores de e-mail ou outros, com certeza lidará com certificados SSL/TLS para garantir a comunicação segura entre os servidores e os clientes (e, talvez, garantir a autenticação dos cientes também).

O modo oficial pelo qual você consegue um certificado válido na internet é um processo de 6 etapas:

  1. Gerar um par de chaves pública/privada (Private Key e Public Key) para seu servidor ou serviço;
  2. Usar essa chave para gerar um CSR (Certificate Signing Request) com as informações de seu servidor;
  3. Enviar esse CSR para uma Certificate Authority (CA) – autoridade de certificação – reconhecida, como a CertSign, Tawthe, Comodo ou outra.
  4. A CA validará o CSR para garantir que você é realmente o dono do servidor e que as informações estão corretas e, estando tudo certo, a CA utilizará as informações constantes em seu CSR para gerar um certificado SSL/TLS que garante a autenticidade de seu servidor, assinando esse certificado.
  5. A CA então enviará para você o certificado assinado do seu servidor, bem como o certificado da própria CA.
  6. Você instalará o seu certificado e o certificado da CA em seu servidor.

Entretanto, em algumas situações, um certificado válido assinado por uma CA reconhecido é caro e nem sempre necessário. Ambientes de testes, intranets, ou acessos administrativos à bancos de dados podem muito bem serem protegidos por certificados SSL/TLS gerados por você mesmo, ou seja: você pode criar sua própria CA para uso pessoal ou empresarial!

Uma vez criada, sua CA pessoal/empresarial pode ser utilizada para gerar e assinar certificados de servidor ou de usuários para uso imediato em seus servidores online.

Este texto mostrará como utilizar o OpenSSL e suas ferramentas de linha de comando para criar sua CA pessoal, gerar chaves, CSR e certificados, além de outras tarefas administrativas que uma CA realiza rotineiramente.

A vantagem de usar o OpenSSL é que ele é o padrão mundial para a implementação de uma infraestrutura de chaves (PKI: public key infrastructure) e fornece um conjunto de ferramentas para implementar e gerenciar certificados.

A desvantagem de usar o OpenSSL é que ele não tem uma interface gráfica, todos os seus comandos são feitos no shell do linux e assim temos que decorar ou lembrar de vários comandos, opções, alternativas e modificadores.

Essa desvantagem pode ser, na realidade, uma vantagem já que qualquer computador recente com linux já trará o OpenSSL instalado, mesmo que não tenha uma interface gráfica habilitada (como é o caso da maioria dos servidores).

Obviamente você não utilizará a linha de comando do OpenSSL para criar uma CA real, que gerencia milhões de certificados de milhões de clientes. Isso é impossível e impraticável na linha de comando e para isso existem softwares comerciais que custam alguns milhares de dólares (também existem alternativas open source, como o EJBCA). Mas o OpenSSL e a linha de comando são mais do que adequados para nossas necessidades.

Um aviso antes de começar! Não sou especialista em OpenSSL: aprendi somente o básico para implantar uma CA pessoal/empresarial e poder administrar meus próprios certificados, e tudo o que aprendi foi baseado nas seguintes fontes (leia os originais se quiser maiores informações e explicações técnicas detalhadas):

1) O OpenSSL está instalado em meu sistema?

Se você usa linux, tenho certeza que sim. Para seguir este tutorial você precisa da versão 1.0.1 do OpenSSL. Para descobrir qual a versão instalada em seu sistema digite o comando:

$ openssl version
OpenSSL 1.0.1f 6 Jan 2014

Se, por um mistério qualquer seu linux não tiver o OpenSSL instalado, utilize o gerenciador de pacotes de sua distribuição para instalar a versão 1.0.1 (ou compile o código fonte).

2) Como funcionará nossa CA?

Nossa CA pessoal/empresarial será dividida, na realidade, em duas autoridades certificadoras:

  • Uma CA raiz, a Root CA, que é intrinsecamente válida e confiável; e
  • Uma CA filha, a Sub CA, que é válida pois foi validada pela Root CA.

A função da Root CA é somente validar e criar a Sub CA, sendo esta a responsável por realmente emitir os certificados finais para usuários e servidores.

Isso é assim por questões de segurança: a Root CA deve ficar protegida, off-line, sendo utilizada somente para gerar a Sub CA.

A Root CA não assina certificados de clientes ou servidores, só de outras Subs CA.

A Sub CA gerará e assinará os certificados de servidores e clientes, em nome da Root CA, e será tecnicamente restrita, ou seja, só poderá gerar e assinar certificados para domínios e hostnames permitidos.

O maior desafio em gerir sua própria CA não é gerar a CA em si, é manter a Root CA e a Sub CA protegidas, com chaves privadas em segurança, principalmente da Root CA. Se um hacker obtém a chave privada de sua Sub CA, a Root CA ainda pode ser utilizada para revogar todos os certificados emitidos pela Sub CA e gerar uma nova Sub CA para emissão de novos certificados. Já se o hacker conseguir a chave privada de sua Root CA, toda a cadeia de certificação torna-se comprometida!

Isto posto, iniciaremos a criação de nossa CA.

3) Preparação da estrutura de diretórios

Vamos iniciar criando um conjunto de diretórios para nossa CA, em nosso diretório HOME, incluindo 3 arquivos especiais (index, serial e crlnumber). Execute os comandos abaixo:

cd $HOME

mkdir CA
cd CA

mkdir root-ca
cd root-ca
mkdir certs crl csr db newcerts private
chmod 700 private

touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber

cd ..

mkdir sub-ca
cd sub-ca
mkdir certs crl csr db newcerts private
chmod 700 private

touch db/index
openssl rand -hex 16 > db/serial
echo 1001 > db/crlnumber

Os comandos acima criaram a seguinte árvore de diretórios:

$HOME/CA
       |> root-ca
       |        |> certs
       |        |> crl
       |        |> csr
       |        |> db
       |        |> newcerts
       |        |> private
       |> sub-ca
       |        |> certs
       |        |> crl
       |        |> csr
       |        |> db
       |        |> newcerts
       |        |> private

A função dos diretórios é a seguinte:

  • certs e newcerts: armazenar os certificados gerados
  • crl: armazenar a lista de certificados revogados
  • csr: armazenar as solicitações de assinatura de certificados (CSR)
  • db: armazenar o banco de dados de certificados (em formato texto)
  • private: armazenar as chaves privadas

Além disso, dentro do diretório db foram criados 3 arquivos especiais:

  • index: armazenará o banco de dados de certificados
  • serial: armazenará o número serial dos certificados
  • crlnumber: armazenará o número da lista de certificados revogados

Obviamente a estrutura acima NÃO É SEGURA pois estamos criando a Root CA no mesmo computador da Sub CA. Idealmente a Root CA deveria ficar em um computador offline, mas para nosso tutorial admitiremos essa falha em nome do aprendizado.

4) Criação da Root CA

Antes de realmente usar os comandos OpenSSL para criarmos a Root CA temos que criar um arquivo de configuração que dirá ao OpenSSL exatamente como a Root CA deve ser criada, que padrões utilizar, que extensões habilitar e etc.

Faça o download do arquivo root-ca.conf de modelo e salve dentro do diretório $HOME/CA/root-ca. Uma descrição detalhada das opções deste arquivo está fora do escopo deste texto mas a maioria das configurações é auto-explicativa e vários comentários indicam a utilidade de cada configuração.

LEIA e MODIFIQUE o arquivo $HOME/CA/root-ca/root-ca.conf conforme suas necessidades! Não prossiga sem antes modificar o arquivo e incluir suas informações pessoais ou de sua empresa. Basta ler o arquivo e os comentários e você saberá quais linhas alterar.

Depois que você modificou o arquivo de configuração, vamos à criação da Root CA.

Em primeiro lugar, temos que criar um chave privada para nossa CA, protegendo essa chave com uma senha forte:

cd $HOME/CA/root-ca

openssl genrsa -aes256 -out private/root-ca.key 4096
Generating RSA private key, 4096 bit long modulus
........................................................................................++
..................................................................................++
e is 65537 (0x10001)
Enter pass phrase for private/root-ca.key: digite_a_senha
Verifying - Enter pass phrase for private/root-ca.key: digite_a_senha

chmod 400 private/root-ca.key

Com isso acabamos de criar nossa chave no arquivo $HOME/CA/root-ca/private/root-ca.key, com permissões de acesso restritas.

Agora vamos usar essa chave privada para gerar um CSR para nosso Root CA. Repare que informamos ao OpenSSL o arquivo de configuração que criamos, indicando qual chave usar e onde armazenar o CSR gerado; note também que os padrões de país, estado, cidade, etc., que o OpenSSL apresenta são configurados no aquivo root-ca.conf que você modificou:

cd $HOME/CA/root-ca

openssl req -new -config root-ca.conf -key private/root-ca.key -out csr/root-ca.csr
Enter pass phrase for private/root-ca.key: senha
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
País (codigo de 2 letras) [BR]:
Estado [Espirito Santo]:
Cidade [Vila Velha]:
Nome da Empresa [Empresa Exemplo Ltda]:
Unidade/Departamento da Empresa [Tecnologia da Informacao]:
Identificador único do certificado (Common Name) [Root CA]:
E-mail [admin@exemplo.com.br]:

Agora já temos a chave e o CSR e só falta usar o OpenSSL para gerar um certificado auto-assinado para a Root CA (claro, se esta é a CA raiz, não existe ninguém acima dela para assinar o certificado para nós, ele obrigatoriamente tem que ser auto-assinado).

Note que informamos ao OpenSSL o arquivo de configuração, dizendo explicitamente qual seção do arquivo será considerada para a geração do Root CA (root_ca):

cd $HOME/CA/root-ca

openssl ca -selfsign -config root-ca.conf -extensions root_ca -in csr/root-ca.csr -notext -out certs/root-ca.crt
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key: senha
Check that the request matches the signature
Signature ok
Certificate Details:
   Serial Number:
      8a:23:e3:c9:5b:20:0c:4b:0e:c0:a8:83:91:e3:c9:c0
   Validity
      Not Before: Oct 27 01:33:33 2015 GMT
      Not After : Oct 22 01:33:33 2035 GMT
   Subject:
      countryName = BR
      stateOrProvinceName = Espirito Santo
      localityName = Vila Velha
      organizationName = Empresa Exemplo Ltda
      organizationalUnitName = Tecnologia da Informacao
      commonName = Root CA
      emailAddress = admin@exemplo.com.br
   X509v3 extensions:
      X509v3 Basic Constraints: critical
      CA:TRUE
   X509v3 Key Usage: critical
      Certificate Sign, CRL Sign
   X509v3 Subject Key Identifier:
      59:36:03:FD:9A:D2:7F:22:A9:1B:8E:D9:24:0A:1B:D2:3C:3A:BA:85
Certificate is to be certified until Oct 22 01:33:33 2035 GMT (7300 days)

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n] y
Write out database with 1 new entries
Data Base Updated

Note que o certificado foi salvo no arquivo certs/root-ca.crt e uma cópia foi armazenada no diretório newcerts.

Para verificar as informações do novo certificado:

openssl x509 -noout -text -in certs/root-ca.crt
Certificate:
   Data:
      Version: 3 (0x2)
      Serial Number:
         8a:23:e3:c9:5b:20:0c:4b:0e:c0:a8:83:91:e3:c9:c0
   Signature Algorithm: sha384WithRSAEncryption
      Issuer: C=BR, ST=Espirito Santo, L=Vila Velha, O=Empresa Exemplo Ltda, OU=Tecnologia da Informacao, CN=Root CA/emailAddress=admin@exemplo.com.br
   Validity
      Not Before: Oct 27 01:33:33 2015 GMT
      Not After : Oct 22 01:33:33 2035 GMT
   Subject: C=BR, ST=Espirito Santo, L=Vila Velha, O=Empresa Exemplo Ltda, OU=Tecnologia da Informacao, CN=Root CA/emailAddress=admin@exemplo.com.br
   Subject Public Key Info:
      Public Key Algorithm: rsaEncryption
      Public-Key: (4096 bit)
      Modulus:
      (várias linhas omitidas aqui)
   Exponent: 65537 (0x10001)
   X509v3 extensions:
      X509v3 Basic Constraints: critical
      CA:TRUE
   X509v3 Key Usage: critical
      Certificate Sign, CRL Sign
   X509v3 Subject Key Identifier:
59:36:03:FD:9A:D2:7F:22:A9:1B:8E:D9:24:0A:1B:D2:3C:3A:BA:85
Signature Algorithm: sha384WithRSAEncryption
      (várias linhas omitidas aqui)

Repare que o certificado foi criado conforme indicamos no arquivo de configuração: 20 anos de validade, com as informações da empresa, chave de 4096 bits, com extensões de CA e servindo apenas para assinar certificados e CRLs. Nesse momento já temos nossa Root CA pronta para o trabalho!

5) Criação da Sub CA

A nossa Sub CA é uma autoridade de certificação intermediária entre a Root CA e os nossos servidores, e serve para gerar e assinar certificados em nome da Root CA.

Como já visto usamos uma CA intermediária por segurança, para garantir que a Root CA seja mantida offline o maior tempo possível. Se a Sub CA é comprometida, a Root CA pode revogar os certificados emitidos pela Sub CA e criar um novo par criptográfico.

A CA intermediária pode ter qualquer nome, aqui escolhi Sub CA para indicar que está abaixo da Root CA. Se você não gostar do nome, pode alterar no arquivo de configuração.

Da mesma forma que na Root CA, antes de realmente usar os comandos OpenSSL para criarmos a Sub CA temos que criar um arquivo de configuração que dirá ao OpenSSL exatamente como a Sub CA deve ser criada, que padrões utilizar, que extensões habilitar e etc.

Faça o download do arquivo sub-ca.conf de modelo e salve dentro do diretório $HOME/CA/sub-ca. Uma descrição detalhada das opções deste arquivo está fora do escopo deste texto mas a maioria das configurações é auto-explicativa e vários comentários indicam a utilidade de cada configuração.

LEIA e MODIFIQUE o arquivo $HOME/CA/sub-ca/sub-ca.conf conforme suas necessidades! Não prossiga sem antes modificar o arquivo e incluir suas informações pessoais ou de sua empresa. Basta ler o arquivo e os comentários e você saberá quais linhas alterar.

Depois que você modificou o arquivo de configuração, vamos à criação da Sub CA.

Em primeiro lugar, temos que criar um chave privada para nossa Sub CA:

cd $HOME/CA/sub-ca

openssl genrsa -aes256 -out private/sub-ca.key 4096
Generating RSA private key, 4096 bit long modulus
..............................................................................................................................................................................++
........................................++
e is 65537 (0x10001)
Enter pass phrase for private/sub-ca.key: digite_a_senha
Verifying - Enter pass phrase for private/sub-ca.key: digite_a_senha

Agora vamos usar essa chave privada para gerar um CSR para nosso Sub CA. Repare que estamos informando ao OpenSSL o arquivo de configuração que criamos, indicando qual chave usar e onde armazenar o CSR gerado; note também que os padrões de país, estado, cidade, etc., que o OpenSSL apresenta são configurados no arquivo sub-ca.conf que você modificou:

cd $HOME/CA/sub-ca

openssl req -config sub-ca.conf -new -key private/sub-ca.key -out csr/sub-ca.csr
Enter pass phrase for private/sub-ca.key: senha
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
País (codigo de 2 letras) [BR]:
Estado [Espirito Santo]:
Cidade [Vila Velha]:
Nome da Empresa [Empresa Exemplo Ltda]:
Unidade/Departamento da Empresa [Tecnologia da Informacao]:
Identificador único do certificado (Common Name) [Sub CA]:
E-mail [admin@exemplo.com.br]:

Agora já temos a chave e o CSR, só falta gerarmos o certificado para a Sub CA. Mas cuidado, pois agora vem a parte da pegadinha, pois a Sub CA não pode gerar um certificado auto-assinado!

Nossa Sub CA gerou um CSR solicitando que alguém gere um certificado para ela. Só que ao contrário da Root CA, que como é a autoridade raiz é intrinsecamente confiável, a Sub CA não é intrinsicamente confiável: a Sub CA precisa que alguém diga que a Sub CA é confiável e que assine um certificado para ela.

Quem pode fazer isso? A Root CA que criamos!

Então nós vamos “enviar” o CSR da Sub CA para a Root CA e a Root CA vai assinar e gerar um certificado para a Sub CA, atestando que a Sub CA em questão é válida e confiável:

cd $HOME/CA/sub-ca
cp csr/sub-ca.csr ../root-ca/csr/

Agora que você já enviou o CSR para uma autoridade certificadora competente (a Root CA), a Root CA vai gerar e assinar o certificado da Sub CA. Note que os comandos a seguir devem ser executados pela Root CA. Repare também que usamos o arquivo de configuração da Root CA (root-ca.conf), mas especificamos explicitamente a extensão sub_ca, que indica a seção no arquivo root-ca.conf onde definimos os parâmetros para as Sub CA criados a partir da Root CA. Note também que a validade de um certificado gerado pela Root CA é de 20 anos, conforme configurado no arquivo root-ca.conf, mas vamos diminuir a validade do certificado da Sub CA para 10 anos:

cd $HOME/CA/root-ca

openssl ca -config root-ca.conf -extensions sub_ca -days 3650 -in csr/sub-ca.csr -notext -out certs/sub-ca.crt
Using configuration from root-ca.conf
Enter pass phrase for ./private/root-ca.key: senha
Check that the request matches the signature
Signature ok
Certificate Details:
   Serial Number:
      8a:23:e3:c9:5b:20:0c:4b:0e:c0:a8:83:91:e3:c9:c1
   Validity
      Not Before: Oct 27 02:26:58 2015 GMT
      Not After : Oct 24 02:26:58 2025 GMT
   Subject:
      countryName = BR
      stateOrProvinceName = Espirito Santo
      localityName = Vila Velha
      organizationName = Empresa Exemplo Ltda
      organizationalUnitName = Tecnologia da Informacao
      commonName = Sub CA
      emailAddress = admin@exemplo.com.br
   X509v3 extensions:
      Authority Information Access:
         CA Issuers - URI:http://root-ca.exemplo.com.br/root-ca.crt
         OCSP - URI:http://ocsp.root-ca.exemplo.com.br
   X509v3 Authority Key Identifier:
     keyid:59:36:03:FD:9A:D2:7F:22:A9:1B:8E:D9:24:0A:1B:D2:3C:3A:BA:85
   X509v3 Basic Constraints: critical
      CA:TRUE, pathlen:0
   X509v3 CRL Distribution Points:
   Full Name:
      URI:http://root-ca.exemplo.com.br/root-ca.crl
   X509v3 Extended Key Usage:
      TLS Web Client Authentication, TLS Web Server Authentication
   X509v3 Key Usage: critical
      Certificate Sign, CRL Sign
   X509v3 Name Constraints:
   Permitted:
      DNS:exemplo.com.br
      DNS:exemplo.org.br
   Excluded:
      IP:0.0.0.0/0.0.0.0
      IP:0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
   X509v3 Subject Key Identifier:
      E9:1B:BC:B0:E8:C0:E6:37:0B:A9:AF:52:F5:EF:71:12:09:66:9C:B8
   Certificate is to be certified until Oct 24 02:26:58 2025 GMT (3650 days)

Sign the certificate? [y/n]: y

1 out of 1 certificate requests certified, commit? [y/n] y
Write out database with 1 new entries
Data Base Updated

Note que o certificado foi salvo no arquivo certs/sub-ca.crt e uma cópia foi armazenada no diretório newcerts.

Para verificar as informações do novo certificado:

openssl x509 -noout -text -in certs/sub-ca.crt
Certificate:
  Data:
    Version: 3 (0x2)
    Serial Number:
      8a:23:e3:c9:5b:20:0c:4b:0e:c0:a8:83:91:e3:c9:c1
  Signature Algorithm: sha384WithRSAEncryption
    Issuer: C=BR, ST=Espirito Santo, L=Vila Velha, O=Empresa Exemplo Ltda, OU=Tecnologia da Informacao, CN=Root CA/emailAddress=admin@exemplo.com.br
  Validity
    Not Before: Oct 27 02:26:58 2015 GMT
    Not After : Oct 24 02:26:58 2025 GMT
  Subject: C=BR, ST=Espirito Santo, L=Vila Velha, O=Empresa Exemplo Ltda, OU=Tecnologia da Informacao, CN=Sub CA/emailAddress=admin@exemplo.com.br
  Subject Public Key Info:
    Public Key Algorithm: rsaEncryption
    Public-Key: (4096 bit)
  Modulus:
    (várias linhas omitidas aqui)
  Exponent: 65537 (0x10001)
  X509v3 extensions:
    Authority Information Access:
      CA Issuers - URI:http://root-ca.exemplo.com.br/root-ca.crt
      OCSP - URI:http://ocsp.root-ca.exemplo.com.br
  X509v3 Authority Key Identifier:
    keyid:59:36:03:FD:9A:D2:7F:22:A9:1B:8E:D9:24:0A:1B:D2:3C:3A:BA:85
  X509v3 Basic Constraints: critical
    CA:TRUE, pathlen:0
  X509v3 CRL Distribution Points:
    Full Name:
      URI:http://root-ca.exemplo.com.br/root-ca.crl
  X509v3 Extended Key Usage:
    TLS Web Client Authentication, TLS Web Server Authentication
  X509v3 Key Usage: critical
    Certificate Sign, CRL Sign
  X509v3 Name Constraints:
  Permitted:
    DNS:exemplo.com.br
    DNS:exemplo.org.br
  Excluded:
    IP:0.0.0.0/0.0.0.0
    IP:0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0
  X509v3 Subject Key Identifier:
    E9:1B:BC:B0:E8:C0:E6:37:0B:A9:AF:52:F5:EF:71:12:09:66:9C:B8
  Signature Algorithm: sha384WithRSAEncryption
    (várias linhas omitidas aqui)

Repare que o certificado foi criado conforme indicamos no arquivo de configuração e nos parâmetros do comando openssl: 10 anos de validade, com as informações da empresa, chave de 4096 bits, com extensões de CA e servindo apenas para assinar certificados e CRLs.

Agora a Root CA precisa “enviar” o certificado assinado para a Sub CA, incluindo o próprio certificado da Root CA para que a Sub CA possa validar o seu certificado:

cd $HOME/CA/root-ca

cp certs/sub-ca.crt ../sub-ca/certs/

cp certs/root-ca.crt ../sub-ca/certs/

Nesse momento a Sub CA acabou de receber de volta seu certificado assinado pela Root CA, bem como o certificado da própria Root CA (que servirá para validar os certificados assinados por essa Root CA).

Como a Sub CA pode checar se seu certificado é válido, ou seja, se realmente está assinado e validado por uma autoridade certificadora confiável (nossa Root CA)? Checando o certificado da Sub CA contra o certificado da Root CA:

cd $HOME/CA/sub-ca

openssl verify -CAfile certs/root-ca.crt certs/sub-ca.crt
certs/sub-ca.crt: OK

O “OK” acima indica que o certificado da Sub CA foi corretamente validado utilizando-se o certificado da Root CA, ou seja, o certificado da Sub CA é válido e assinado pela Root CA.

A Sub CA precisa ainda realizar uma última tarefa antes de poder emitir certificados para servidores e clientes: gerar um certificado com a cadeia de certificação, ou seja, gerar um arquivo que contenha o certificado da própria Sub CA, juntamente com o certificado da Root CA.

Essa cadeia de certificação é enviada aos clientes (servidores ou usuários) que tenham certificados gerados pela Sub CA, de modo que os próprios clientes (servidores ou usuários) também possam validar seus próprios certificados e ter certeza de que a SubCA e a Root CA são válidas.

Quando os clientes (servidores ou usuários) receberem seus certificados gerados pela Sub CA eles podem validá-los de modo semelhante ao que foi feito quando a Root CA enviou seu certificado para a Sub CA, só que nesse caso a Sub CA também deve enviar seu certificado para os clientes agregando, além do próprio certificado, o certificado da Root CA em uma “cadeia de certificação”. Para fazer isso:

cd $HOME/CA/sub-ca/certs

cat sub-ca.crt root-ca.crt > ca-chain.crt

6) Criação de certificados para servidores

Certificados para servidores são utilizados para garantir a conexão segura, criptografada, entre aplicações clientes e seus servidores como, por exemplo, um servidor web, um servidor de e-mails, um servidor de banco de dados, etc.

Os certificados para os servidores geralmente têm validade de 1 ano e tamanho de chaves de 2048 bits.

Além disso, as chaves privadas dos certificados para servidores são geradas sem senha para evitar que o reinício de algum serviço obrigue a presença física de um administrador de sistemas para informar a senha do certificado. Por exemplo: se seu servidor web utiliza uma chave privada com senha, toda vez que você reiniciar o servidor, alguém precisará informar, manualmente, a senha da chave privada do certificado caso contrário o servidor web não será inicializado. Assim, por comodidade, as chaves privadas dos certificados de servidores são geralmente criadas sem senha e salvas em um diretório restrito com permissões mais restritas ainda (400).

Uma CA real não cria as chaves nem o CSR para o servidor. O terceiro interessado em proteger a comunicação com seu servidor é que tem que gerar as chaves e o CSR, enviar esse CSR para a CA oficial e, somente então, a CA oficial gera e assina um certificado para o servidor.

Como nós somos nossa própria CA, usaremos a Sub CA para gerar as chaves, o CSR e o certificado para o servidor web02.exemplo.com.br. Inicialmente, vamos gerar a chave privada para o servidor, sem senha, com tamanho de 2048 bits:

cd $HOME/CA/sub-ca

openssl genrsa -out private/web02.exemplo.com.br.key 2048
Generating RSA private key, 2048 bit long modulus
...............+++
................+++
e is 65537 (0x10001)

chmod 400 private/web02.exemplo.com.br.key

Agora vamos gerar um CSR com as informações corretas para nosso servidor.

A configuração mais importante é o Common Name, que deve apontar para o hostname totalmente qualificado, válido na internet, de seu servidor ou serviço (pode ser um registro do tipo A, MX ou CNAME, mas deve obrigatoriamente ser resolvido para um IP). Repare que usamos o arquivo de configuração do nosso próprio Sub CA e a chave privada gerada anteriormente, e que os padrões para o país, estado, cidade, etc. foram configurados no arquivo sub-ca.conf (ATENÇÃO: altere o common name para o hostname completo do servidor!):

cd $HOME/CA/sub-ca

openssl req -new -config sub-ca.conf -key private/web02.exemplo.com.br.key -out csr/web02.exemplo.com.br.csr
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
País (codigo de 2 letras) [BR]:
Estado [Espirito Santo]:
Cidade [Vila Velha]:
Nome da Empresa [Empresa Exemplo Ltda]:
Unidade/Departamento da Empresa [Tecnologia da Informacao]:
Identificador único do certificado (Common Name) [Sub CA]:web02.exemplo.com.br
E-mail [admin@exemplo.com.br]:

Agora usaremos a Sub CA para gerar e assinar o certificado do servidor. Note que o arquivo de configuração utilizado é o da Sub CA, mas especificamente informamos a extensão server_cert que diz para o OpenSSL gerar um certificado de servidor:

cd $HOME/CA/sub-ca

openssl ca -config sub-ca.conf -extensions server_cert -in csr/web02.exemplo.com.br.csr -notext -out certs/web02.exemplo.com.br.crt
Using configuration from sub-ca.conf
Enter pass phrase for ./private/sub-ca.key: senha
Check that the request matches the signature
Signature ok
Certificate Details:
   Serial Number:
      a1:4f:42:f2:19:75:e5:bb:fc:eb:b8:b4:9c:76:ed:ac
   Validity
      Not Before: Oct 27 18:03:16 2015 GMT
      Not After : Oct 26 18:03:16 2016 GMT
   Subject:
      countryName = BR
      stateOrProvinceName = Espirito Santo
      localityName = Vila Velha
      organizationName = Empresa Exemplo Ltda
      organizationalUnitName = Tecnologia da Informacao
      commonName = web02.exemplo.com.br
      emailAddress = admin@exemplo.com.br
   X509v3 extensions:
      X509v3 Basic Constraints: critical
         CA:FALSE
   Netscape Cert Type:
      SSL Server
   Netscape Comment:
      Certificado Servidor gerado pelo OpenSSL
   X509v3 Subject Key Identifier:
      1A:1A:21:F1:63:79:88:80:EC:28:0E:92:78:C5:EF:60:31:CE:48:EC
   X509v3 Authority Key Identifier:
     keyid:E9:1B:BC:B0:E8:C0:E6:37:0B:A9:AF:52:F5:EF:71:12:09:66:9C:B8
   DirName:/C=BR/ST=Espirito Santo/L=Vila Velha/O=Empresa Exemplo Ltda/OU=Tecnologia da Informacao/CN=Root CA/emailAddress=admin@exemplo.com.br
   serial:8A:23:E3:C9:5B:20:0C:4B:0E:C0:A8:83:91:E3:C9:C1
   Authority Information Access:
      CA Issuers - URI:http://sub-ca.exemplo.com.br/sub-ca.crt
      OCSP - URI:http://ocsp.sub-ca.exemplo.com.br
   X509v3 Key Usage: critical
      Digital Signature, Key Encipherment
   X509v3 Extended Key Usage:
      TLS Web Client Authentication, TLS Web Server Authentication
   X509v3 CRL Distribution Points:
      Full Name:
         URI:http://sub-ca.exemplo.com.br/sub-ca.crl
Certificate is to be certified until Oct 26 18:03:16 2016 GMT (365 days)

Sign the certificate? [y/n]: y

1 out of 1 certificate requests certified, commit? [y/n] y
Write out database with 1 new entries
Data Base Updated

O certificado foi salvo no arquivo certs/web02.exemplo.com.br.crt e uma cópia foi armazenada no diretório newcerts.

Para verificar as informações do novo certificado (output omitido aqui, é semelhando aos outros já apresentados; estudo o output e repare que o certificado não é um CA, tem validade de 1 ano e é do tipo servidor):

openssl x509 -noout -text -in certs/web02.exemplo.com.br.crt

Para verificar se o certificado está válido, vamos verificá-lo contra a cadeia de certificação:

openssl verify -CAfile certs/ca-chain.crt certs/web02.exemplo.com.br.crt
certs/web02.exemplo.com.br.crt: OK

Como tudo está pronto, só precisamos instalar o certificado no servidor. Para fazer isso você precisará colocar os 3 arquivos abaixo no servidor e ajustar a configuração específica do seu aplicativo (consulte a documentação específica do aplicativo em questão – Apache, PostgreSQL, Zimbra, etc. –, para saber exatamente como configurar o aplicativo para utilizar os arquivos abaixo):

  • certificado do servidor (com a extensão crt)
  • chave privada do certificado (com a extensão key)
  • a cadeia de certificação que inclui os certificados da Root CA e da Sub CA (arquivo ca-chain.crt)

7) Criação de certificados para usuários/clientes

Um outro tipo de certificado que podemos criar é o certificado de usuário/cliente, que é um certificado com objetivo diferente do certificado para servidores.

Enquanto o certificado de servidor tem como objetivo principal criptografar a comunicação entre o software cliente e o software servidor, o certificado cliente tem como objetivo principal confirmar a identidade do usuário para o servidor.

Por exemplo: você já instalou um certificado servidor em um banco de dados e comunicação está segura mas, mesmo assim, o banco de dados só permitirá acesso se o usuário apresentar um certificado de usuário/cliente, assinado por uma CA válida e reconhecida pelo servidor (nossa Sub CA!), que autentique o cliente, ou seja, que garanta que o cliente é quem ele diz que é. Se o cliente não apresentar um certificado válido, o banco de dados não pode autenticar o cliente e assim não permitirá o acesso. Um outro uso comum deste tipo de certificado é a assinatura de mensagens de e-mails dos usuários, garantindo que o remetente do e-mail é quem ele diz ser.

Os certificados de usuários/clientes também têm, geralmente, validade de 1 ano e tamanho de chaves de 2048 bits.

As chaves privadas dos certificados de usuários/clientes podem ser geradas com senha ou sem senha, dependendo da política da empresa ou de sua política pessoal.

Se você tem como garantir que seu certificado de usuário/cliente será sempre mantido em segurança, pode gerar a chave sem senha. Se você não confia nisso, gere a chave com senha mas lembre-se que toda vez que precisar do certificado terá que digitar a senha (o que teoricamente não é problema, visto que esses certificados são utilizados geralmente de forma manual pelo usuário).

De qualquer forma as chaves privadas dos certificados de usuários/clientes são geralmente criadas (com ou sem senha) e salvas em um diretório restrito com permissões mais restritas ainda (400).

Como nós somos nossa própria CA, usaremos nossa Sub CA para gerar as chaves, o CSR e o certificado. É interessante estabelecer um padrão de nome para as chaves/certificados dos usuários, por exemplo o endereço de e-mail corporativo.

Inicialmente, vamos gerar a chave privada para o usuário, COM senha, com tamanho de 2048 bits (se quiser gerar uma chave SEM senha, basta retirar a opção “-aes256” do comando abaixo):

cd $HOME/CA/sub-ca

openssl genrsa -aes256 -out private/abrantes.filho.at.exemplo.com.br.key 2048
Generating RSA private key, 2048 bit long modulus
.................................................+++
.....................+++
e is 65537 (0x10001)
Enter pass phrase for private/abrantes.filho.at.exemplo.com.br.key:
Verifying - Enter pass phrase for private/abrantes.filho.at.exemplo.com.br.key:

chmod 400 private/abrantes.filho.at.exemplo.com.br.key

Agora vamos gerar um CSR com as informações corretas para o certificado de usuário. A configuração mais importante é o Common Name, que tem que ser um identificador único, por exemplo o endereço de e-mail do usuário, ou o nome do usuário. Repare que usamos o arquivo de configuração do nosso próprio Sub CA e a chave privada gerada anteriormente (e novamente os padrões foram configurados no arquivo sub-ca.conf):

cd $HOME/CA/sub-ca

openssl req -new -config sub-ca.conf -key private/abrantes.filho.at.exemplo.com.br.key -out csr/abrantes.filho.at.exemplo.com.br.csr
Enter pass phrase for private/abrantes.filho.at.exemplo.com.br.key: senha
You are about to be asked to enter information that will be incorporated into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
País (codigo de 2 letras) [BR]:
Estado [Espirito Santo]:
Cidade [Vila Velha]:
Nome da Empresa [Empresa Exemplo Ltda]:
Unidade/Departamento da Empresa [Tecnologia da Informacao]:
Identificador único do certificado (Common Name) [Sub CA]:abrantes.filho@exemplo.com.br
E-mail [admin@exemplo.com.br]:

Agora usaremos a Sub CA para gerar e assinar o certificado do usuário. Note que o arquivo de configuração utilizado é o da Sub CA, mas especificamente informamos a extensão usr_cert que diz para o OpenSSL gerar um certificado de usuário/cliente:

cd $HOME/CA/sub-ca

openssl ca -config sub-ca.conf -extensions usr_cert -in csr/abrantes.filho.at.exemplo.com.br.csr -notext -out certs/abrantes.filho.at.exemplo.com.br.crt
Using configuration from sub-ca.conf
Enter pass phrase for ./private/sub-ca.key:
Check that the request matches the signature
Signature ok
Certificate Details:
   Serial Number:
      a1:4f:42:f2:19:75:e5:bb:fc:eb:b8:b4:9c:76:ed:ad
   Validity
      Not Before: Oct 27 18:51:13 2015 GMT
      Not After : Oct 26 18:51:13 2016 GMT
   Subject:
      countryName = BR
      stateOrProvinceName = Espirito Santo
      localityName = Vila Velha
      organizationName = Empresa Exemplo Ltda
      organizationalUnitName = Tecnologia da Informacao
      commonName = abrantes.filho@exemplo.com.br
      emailAddress = admin@exemplo.com.br
   X509v3 extensions:
      X509v3 Basic Constraints: critical
         CA:FALSE
   Netscape Cert Type:
      SSL Client, S/MIME
   Netscape Comment:
      Certificado Cliente gerado pelo OpenSSL
   X509v3 Subject Key Identifier:
      E8:DE:CC:E8:17:E0:1A:CD:AB:F5:67:6F:BD:13:98:7B:2D:73:07:D3
   X509v3 Authority Key Identifier:
     keyid:E9:1B:BC:B0:E8:C0:E6:37:0B:A9:AF:52:F5:EF:71:12:09:66:9C:B8
DirName:/C=BR/ST=Espirito Santo/L=Vila Velha/O=Empresa Exemplo Ltda/OU=Tecnologia da Informacao/CN=Root CA/emailAddress=admin@exemplo.com.br
serial:8A:23:E3:C9:5B:20:0C:4B:0E:C0:A8:83:91:E3:C9:C1
   Authority Information Access:
      CA Issuers - URI:http://sub-ca.exemplo.com.br/sub-ca.crt
      OCSP - URI:http://ocsp.sub-ca.exemplo.com.br
   X509v3 Key Usage: critical
      Digital Signature, Non Repudiation, Key Encipherment
   X509v3 Extended Key Usage:
      TLS Web Client Authentication, E-mail Protection
   X509v3 CRL Distribution Points:
      Full Name:
         URI:http://sub-ca.exemplo.com.br/sub-ca.crl
Certificate is to be certified until Oct 26 18:51:13 2016 GMT (365 days)

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

O certificado foi salvo no arquivo certs/abrantes.filho.at.exemplo.com.br.crt e uma cópia foi armazenada no diretório newcerts.

Para verificar as informações do novo certificado (output omitido):

openssl x509 -noout -text -in certs/abrantes.filho.at.exemplo.com.br.crt

Para verificar se o certificado está válido, vamos verificá-lo contra a cadeia de certificação:

openssl verify -CAfile certs/ca-chain.crt certs/abrantes.filho.at.exemplo.com.br.crt
certs/abrantes.filho.at.exemplo.com.br.crt: OK

Como tudo está pronto, precisamos enviar a chave, o certificado e a cadeia de certificação para o usuário, e a cadeia de certificação para o servidor.

Você terá também que configurar sua aplicação/servidor para utilizar a cadeia de certificação para validar os certificados que os usuários apresentam ao tentar acessar o serviço/servidor. Para isso consulte a documentação específica de seu software. Em geral você sempre fará o seguinte:

  • enviar o certificado do usuário para o usuário (com a extensão crt)
  • enviar a chave privada do certificado para o usuário (com a extensão key)
  • enviar a a cadeia de certificação (arquivo ca-chain.crt) para o usuário
  • enviar a cadeia de certificação para o sevidor

8) Finalizando:

Lembre-se que o maior desafio de manter sua própria CA é manter a segurança da Root CA e da Sub CA. Idealmente a Root CA deve ficar em um computador totalmente offline, sendo usada somente para gerar a Sub CA e as listas de revogação de certificados das Sub CA, quando necessário.

Nossa CA já está pronta e configurada para emitir certificados de servidor e de usuários/clientes para nosso uso pessoal ou empresarial, de maneira simples e rápida. Comece a gerar os certificados de que necessita e mão à obra!

Só um último aviso: à medida que você gera e emite certificados, alguns serão perdidos, senhas serão esquecidas ou o prazo de validade expirará. Nesses casos você precisa revogar o certificado e emitir um novo. O processo de revogação de certificados, bem como a geração da CRL (Lista de Certificados Revogados) será mostrado na parte 2 deste texto. Até lá!