Estou esquecendo de algo? Essa é a maneira correta de criar um certificado autoassinado?
É fácil criar um certificado autoassinado. Você acabou de usar o openssl req
comando Pode ser complicado criar um que possa ser consumido pela maior seleção de clientes, como navegadores e ferramentas de linha de comando.
É difícil porque os navegadores têm seu próprio conjunto de requisitos e são mais restritivos que o IETF . Os requisitos usados pelos navegadores estão documentados nos fóruns da CA / navegador (consulte as referências abaixo). As restrições surgem em duas áreas principais: (1) âncoras confiáveis e (2) nomes DNS.
Os navegadores modernos (como o warez que estamos usando em 2014/2015) desejam um certificado que seja vinculado a uma âncora de confiança e desejam que os nomes DNS sejam apresentados de maneiras específicas no certificado. E os navegadores estão se movendo ativamente contra certificados de servidor autoassinado.
Alguns navegadores não facilitam exatamente a importação de um certificado de servidor autoassinado. Na verdade, você não pode usar alguns navegadores, como o Android. Portanto, a solução completa é se tornar sua própria autoridade.
Na ausência de se tornar sua própria autoridade, é necessário acertar os nomes DNS para dar ao certificado a maior chance de sucesso. Mas eu encorajaria você a se tornar sua própria autoridade. É fácil tornar-se sua própria autoridade e contornar todos os problemas de confiança (em quem é melhor confiar do que você?).
Este provavelmente não é o site que você está procurando!
O certificado de segurança do site não é confiável!
Isso ocorre porque os navegadores usam uma lista predefinida de âncoras confiáveis para validar certificados de servidor. Um certificado autoassinado não volta para uma âncora confiável.
A melhor maneira de evitar isso é:
- Crie sua própria autoridade (ex .: torne-se uma autoridade de certificação )
- Crie uma solicitação de assinatura de certificado (CSR) para o servidor
- Assine o CSR do servidor com sua chave CA
- Instale o certificado do servidor no servidor
- Instale o certificado da CA no cliente
Etapa 1 - Crie sua própria autoridade significa apenas criar um certificado autoassinado com CA: true
o uso adequado da chave. Isso significa que o Assunto e o emissor são a mesma entidade, a CA é configurada como verdadeira em Restrições básicas (também deve ser marcada como crítica), o uso da chave é keyCertSign
e crlSign
(se você estiver usando CRLs) e o Identificador de chave do sujeito (SKI) é o mesmo que o AKI ( Authority Key Identifier ).
Para se tornar sua própria autoridade de certificação, consulte * Como você assina uma solicitação de assinatura de certificado com sua autoridade de certificação? no estouro de pilha. Em seguida, importe sua CA para o Trust Store usado pelo navegador.
As etapas 2 a 4 são basicamente o que você faz agora para um servidor público ao recrutar os serviços de uma CA como a Startcom ou CAcert . As etapas 1 e 5 permitem evitar a autoridade de terceiros e agir como sua própria autoridade (em quem é melhor confiar do que você?).
A próxima melhor maneira de evitar o aviso do navegador é confiar no certificado do servidor. Mas alguns navegadores, como o navegador padrão do Android, não permitem isso. Portanto, nunca funcionará na plataforma.
A questão de navegadores (e outros agentes de usuário semelhantes) não confiarem em certificados autoassinados será um grande problema na Internet das Coisas (IoT). Por exemplo, o que acontecerá quando você se conectar ao termostato ou à geladeira para programá-lo? A resposta é: nada de bom no que diz respeito à experiência do usuário.
O grupo de trabalho WebAppSec do W3C está começando a analisar o problema. Consulte, por exemplo, Proposta: Marcando HTTP como Não Seguro .
Como criar um certificado autoassinado com OpenSSL
Os comandos abaixo e o arquivo de configuração criam um certificado autoassinado (também mostra como criar uma solicitação de assinatura). Eles diferem de outras respostas em um aspecto: os nomes DNS usados para o certificado autoassinado estão no Nome Alternativo do Assunto (SAN) e não no Nome Comum (CN) .
Os nomes DNS são colocados na SAN através do arquivo de configuração com a linha subjectAltName = @alternate_names
(não há como fazê-lo através da linha de comando). Depois, há uma alternate_names
seção no arquivo de configuração (você deve ajustar isso de acordo com o seu gosto):
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# IP.1 = 127.0.0.1
# IP.2 = ::1
É importante colocar o nome DNS na SAN e não o CN, porque ambos o IETF eo CA / Fórum do navegador especificar a prática. Eles também especificam que os nomes DNS na CN são preteridos (mas não proibidos). Se você colocar um nome DNS no CN, ele deverá ser incluído na SAN nas políticas da CA / B. Portanto, você não pode evitar o uso do Nome alternativo do assunto.
Se você não colocar nomes DNS na SAN, o certificado falhará na validação em um navegador e outros agentes de usuário que sigam as diretrizes do CA / Forum do navegador.
Relacionado: os navegadores seguem as políticas do CA / Browser Forum; e não as políticas da IETF. Essa é uma das razões pelas quais um certificado criado com o OpenSSL (que geralmente segue o IETF) às vezes não é validado em um navegador (os navegadores seguem o CA / B). São padrões diferentes, têm políticas de emissão diferentes e requisitos de validação diferentes.
Crie um certificado autoassinado (observe a adição da -x509
opção):
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
Crie uma solicitação de assinatura (observe a falta de -x509
opção):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
Imprima um certificado autoassinado :
openssl x509 -in example-com.cert.pem -text -noout
Imprima uma solicitação de assinatura :
openssl req -in example-com.req.pem -text -noout
Arquivo de configuração (passado via -config
opção)
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY
localityName = Locality Name (eg, city)
localityName_default = New York
organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company
emailAddress = Email Address
emailAddress_default = test@example.com
# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1
# IPv6 localhost
# DNS.8 = ::1
Pode ser necessário fazer o seguinte no Chrome. Caso contrário, o Chrome poderá reclamar que um Nome Comum é inválido ( ERR_CERT_COMMON_NAME_INVALID
) . Não tenho certeza de qual é a relação entre um endereço IP na SAN e uma CN nessa instância.
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
Existem outras regras relacionadas ao tratamento de nomes DNS nos certificados X.509 / PKIX. Refira estes documentos para as regras:
As RFC 6797 e RFC 7469 são listadas, porque são mais restritivas que os outros RFCs e documentos CA / B. Os RFCs 6797 e 7469 também não permitem um endereço IP.