O OpenSSL é o canivete suíço do gerenciamento de certificados SSL/TLS. Seja para gerar uma chave privada, inspecionar um certificado prestes a expirar, criar uma Autoridade Certificadora para serviços internos ou depurar falhas no handshake TLS, o CLI do openssl resolve tudo. Este guia percorre todas as operações essenciais de certificados — da geração de chaves à validação da cadeia — com comandos práticos que você pode executar imediatamente em qualquer servidor Linux.
Pré-requisitos
- OpenSSL instalado (versão 1.1.x ou 3.x — verifique com
openssl version) - Familiaridade básica com a linha de comandos do Linux
- Acesso root ou sudo se instalar certificados em nível de sistema
- Compreensão de certificados SSL/TLS (pares de chave pública/privada, CAs, cadeias de confiança)
Geração de Chaves e Requisições de Assinatura de Certificado
Todo ciclo de vida de certificado começa com uma chave privada. O OpenSSL suporta RSA, ECDSA e Ed25519. RSA de 4096 bits e ECDSA P-256 são as escolhas mais comuns para produção.
Gerar uma chave privada RSA:
openssl genrsa -out key.pem 4096
Gerar uma chave ECDSA (mais rápida, menor, igualmente segura):
openssl ecparam -genkey -name prime256v1 | openssl ec -out ec-key.pem
Criar uma Requisição de Assinatura de Certificado (CSR):
openssl req -new -key key.pem -out request.csr
Será solicitado o preenchimento dos campos do Nome Distinto (DN). O campo mais crítico é Common Name (CN) — deve corresponder ao seu nome de domínio. Para TLS moderno, os Subject Alternative Names (SANs) são obrigatórios. Use um arquivo de configuração para defini-los:
cat > san.conf <<EOF
[req]
req_extensions = v3_req
distinguished_name = dn
[dn]
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = example.com
DNS.2 = www.example.com
EOF
openssl req -new -key key.pem -out request.csr -config san.conf
Inspecionar o CSR antes de enviá-lo:
openssl req -text -noout -in request.csr
Criação de Certificados Autoassinados
Certificados autoassinados são ideais para serviços internos, ambientes de desenvolvimento e APIs privadas onde uma CA pública não é necessária.
Criar um certificado autoassinado em um único comando:
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem \
-sha256 -days 365 -nodes \
-subj "/CN=example.com/O=MyOrg/C=US"
O sinalizador -nodes ignora a criptografia de senha na chave privada. Remova-o para chaves armazenadas offline.
Autoassinado com SANs (obrigatório para navegadores modernos):
openssl req -x509 -newkey rsa:4096 \
-keyout key.pem -out cert.pem \
-sha256 -days 365 -nodes \
-subj "/CN=example.com" \
-addext "subjectAltName=DNS:example.com,DNS:www.example.com"
Criação de uma Autoridade Certificadora Interna
Uma CA interna permite emitir certificados confiáveis para todos os serviços da organização sem depender de uma CA pública. Esta é a abordagem padrão para clusters Kubernetes, APIs internas e infraestrutura de VPN.
Criar a chave da CA e o certificado raiz autoassinado:
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 3650 \
-key ca-key.pem -out ca-cert.pem \
-subj "/CN=My Internal CA/O=MyOrg/C=US"
Assinar um CSR de servidor com sua CA:
openssl x509 -req -days 365 \
-in request.csr \
-CA ca-cert.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem \
-extfile san.conf -extensions v3_req
Inspeção e Validação de Certificados
Ler um certificado local:
openssl x509 -text -noout -in cert.pem
Verificar apenas a data de expiração:
openssl x509 -enddate -noout -in cert.pem
Inspecionar o certificado de um servidor remoto:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -text -noout
Verificar que o certificado corresponde à chave privada:
openssl rsa -noout -modulus -in key.pem | md5sum
openssl x509 -noout -modulus -in cert.pem | md5sum
Comparação
| Recurso | OpenSSL CLI | cfssl | easy-rsa | certbot |
|---|---|---|---|---|
| Certificados autoassinados | Sim | Sim | Sim | Não |
| CA interna | Sim | Sim | Sim | Não |
| Integração com CA pública | Não | Não | Não | Sim (Let’s Encrypt) |
| Suporte a SAN | Sim (arquivo config) | Sim | Sim | Sim |
| Exportação PKCS#12 | Sim | Parcial | Não | Sim |
| Curva de aprendizado | Média | Baixa | Baixa | Muito baixa |
Cenário Real
Você tem um servidor Nginx de produção apresentando erros de handshake SSL. Usuários reportam “NET::ERR_CERT_COMMON_NAME_INVALID” no Chrome. Veja o fluxo de diagnóstico:
# Passo 1: verificar qual certificado o servidor está servindo
echo | openssl s_client -connect myserver.com:443 -servername myserver.com 2>/dev/null \
| openssl x509 -text -noout | grep -A3 "Subject Alternative Name"
# Passo 2: se não houver SANs, regenerar com a abordagem san.conf
# Passo 3: verificar correspondência chave/certificado após regeneração
openssl rsa -noout -modulus -in /etc/nginx/ssl/key.pem | md5sum
openssl x509 -noout -modulus -in /etc/nginx/ssl/cert.pem | md5sum
# Passo 4: testar o handshake completo
openssl s_client -connect myserver.com:443 -servername myserver.com
Armadilhas e Casos Especiais
SANs são obrigatórios desde 2017. O Chrome 58 parou de suportar certificados com apenas CN. Sempre inclua subjectAltName mesmo para certificados de domínio único.
Permissões do arquivo de chave importam. A chave privada deve ser legível apenas pelo processo que a necessita: chmod 600 key.pem. Nginx e Apache recusarão inicialização se a chave for legível por todos.
Chaves com senha bloqueiam reinicializações automatizadas. Use -nodes ao gerar chaves para servidores web.
A ordem da cadeia de certificados importa. Nginx e Apache esperam o certificado do servidor primeiro, seguido pelos certificados intermediários, no mesmo arquivo PEM.
Diferença de horário quebra a validação. Se o relógio do servidor estiver adiantado ou atrasado mais de alguns minutos, openssl verify falhará com “certificate not yet valid”.
Exportar para o formato PKCS#12 para Windows/Java:
openssl pkcs12 -export \
-out bundle.p12 \
-inkey key.pem \
-in cert.pem \
-certfile ca-cert.pem
Solução de Problemas
“verify error:num=20:unable to get local issuer certificate” — O certificado CA não está no seu armazenamento de confiança. Passe-o explicitamente: openssl verify -CAfile ca-cert.pem cert.pem.
“private key does not match the certificate public key” — Os hashes do módulo diferem. Você regenerou a chave sem regenerar o certificado, ou misturou os arquivos.
“no shared cipher” — O cliente e o servidor não conseguem acordar um conjunto de cifras. Verifique a configuração SSL do servidor.
“certificate has expired” — Verifique com openssl x509 -enddate -noout -in cert.pem e renove com o mesmo CSR.
Resumo
- Gere chaves RSA 4096 ou ECDSA P-256 com
openssl genrsaouopenssl ecparam - Sempre inclua Subject Alternative Names — certificados com apenas CN são rejeitados por navegadores modernos
- Use um arquivo de configuração com seção
[alt_names]para adicionar SANs a CSRs e certificados autoassinados - Inspecione qualquer certificado com
openssl x509 -text -noout -in cert.pem - Verifique a correspondência chave/certificado comparando hashes MD5 do módulo
- Crie uma CA interna para Kubernetes, VPN e microsserviços sem dependências externas
- Exporte para o formato PKCS#12 para keystores Java e armazenamentos de certificados Windows
- Mantenha as chaves privadas da CA criptografadas, offline e com backups separados