Gerando um certificado autoassinado com o openssl que funciona no Chrome 58

41

A partir do Chrome 58, ele não aceita mais certificados auto-assinados que dependem de Common Name : link $ 3ACanary% 7Coor: relevância% 7Cspell: false

Em vez disso, é necessário usar Subject Alt Name . Anteriormente, segui este guia sobre como gerar um certificado autoassinado: link que funcionou muito bem porque Eu solicitei os arquivos server.crt e server.key para o que estou fazendo. Agora preciso gerar novos certificados que incluam SAN , mas todas as minhas tentativas não funcionaram com o Chrome 58.

Aqui está o que eu fiz:

Eu segui os passos no artigo Heroku acima mencionado para gerar a chave. Eu então escrevi um novo arquivo de configuração do OpenSSL:

[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
req_extensions      = san
extensions          = san
[ req_distinguished_name ]
countryName         = US
stateOrProvinceName = Massachusetts
localityName        = Boston
organizationName    = MyCompany
[ san ]
subjectAltName      = DNS:dev.mycompany.com

Em seguida, gerou o server.crt com o seguinte comando:

openssl req \
-new \
-key server.key \
-out server.csr \
-config config.cnf \
-sha256 \
-days 3650

Estou em um Mac, por isso, abri o arquivo server.crt com o Keychain e o adicionei aos meus Certificados do sistema. Em seguida, defino-o como Always Trust .

Com exceção do arquivo de configuração para definir o valor da SAN, essas foram as etapas semelhantes usadas em versões anteriores do Chrome para gerar e confiar no certificado autoassinado.

No entanto, depois disso, ainda recebo o ERR_CERT_COMMON_NAME_INVALID no Chrome 58.

    
por bcardarella 21.04.2017 / 15:50

6 respostas

51

Minha solução:

openssl req \
    -newkey rsa:2048 \
    -x509 \
    -nodes \
    -keyout server.key \
    -new \
    -out server.crt \
    -subj /CN=dev.mycompany.com \
    -reqexts SAN \
    -extensions SAN \
    -config <(cat /System/Library/OpenSSL/openssl.cnf \
        <(printf '[SAN]\nsubjectAltName=DNS:dev.mycompany.com')) \
    -sha256 \
    -days 3650

Status: funciona para mim

    
por 21.04.2017 / 17:55
12

No Windows, salve este script na sua pasta SSL como makeCERT.bat. Ele criará esses arquivos: example.cnf, example.crt, example.key

@echo off

REM IN YOUR SSL FOLDER, SAVE THIS FILE AS: makeCERT.bat
REM AT COMMAND LINE IN YOUR SSL FOLDER, RUN: makecert
REM IT WILL CREATE THESE FILES: example.cnf, example.crt, example.key
REM IMPORT THE .crt FILE INTO CHROME Trusted Root Certification Authorities
REM REMEMBER TO RESTART APACHE OR NGINX AFTER YOU CONFIGURE FOR THESE FILES

REM PLEASE UPDATE THE FOLLOWING VARIABLES FOR YOUR NEEDS.
SET HOSTNAME=example
SET DOT=com
SET COUNTRY=US
SET STATE=KS
SET CITY=Olathe
SET ORGANIZATION=IT
SET ORGANIZATION_UNIT=IT Department
SET EMAIL=webmaster@%HOSTNAME%.%DOT%

(
echo [req]
echo default_bits = 2048
echo prompt = no
echo default_md = sha256
echo x509_extensions = v3_req
echo distinguished_name = dn
echo:
echo [dn]
echo C = %COUNTRY%
echo ST = %STATE%
echo L = %CITY%
echo O = %ORGANIZATION%
echo OU = %ORGANIZATION_UNIT%
echo emailAddress = %EMAIL%
echo CN = %HOSTNAME%.%DOT%
echo:
echo [v3_req]
echo subjectAltName = @alt_names
echo:
echo [alt_names]
echo DNS.1 = *.%HOSTNAME%.%DOT%
echo DNS.2 = %HOSTNAME%.%DOT%
)>%HOSTNAME%.cnf

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout %HOSTNAME%.key -days 3560 -out %HOSTNAME%.crt -config %HOSTNAME%.cnf
    
por 18.05.2017 / 20:30
10

Aqui está uma solução que funciona para mim:

Crie a chave e o certificado da CA

# openssl genrsa -out server_rootCA.key 2048
# openssl req -x509 -new -nodes -key server_rootCA.key -sha256 -days 3650 -out server_rootCA.pem

Crie server_rootCA.csr.cnf

# server_rootCA.csr.cnf
[req]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[dn]
C=DE
ST=Berlin
L=NeuKoelln
O=Weisestrasse
OU=local_RootCA
[email protected]
CN = server.berlin

Crie o arquivo de configuração v3.ext

# v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = server.berlin

Criar chave do servidor

# openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server_rootCA.csr.cnf )

Criar certificado de servidor

# openssl x509 -req -in server.csr -CA server_rootCA.pem -CAkey server_rootCA.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile v3.ext

Adicione o cert e a chave para o arquivo de site do Apache2, a seção HTTPS (porta 443)

SSLCertificateFile    /etc/apache2/ssl/server.crt
SSLCertificateKeyFile    /etc/apache2/ssl/server.key

Copie server_rootCA.pem do servidor para sua máquina.

# scp [email protected]:~/server_rootCA.pem .

.. e adicione-o ao navegador do Chromium

Chromium -> Setting -> (Advanced) Manage Certificates -> Import -> 'server_rootCA.pem'

VOCÊ ESTÁ TUDO FEITO!

P.S. Em vez de criar um CA funcional & Par de certificados do servidor (de acordo com as instruções acima) você pode simplesmente desabilitar os cabeçalhos de HSTS na sua configuração do servidor HTTP. Isso impedirá que o Chromium imponha o HTTPS e permitirá que os usuários cliquem em "Avançado → prossiga para o seu.url (inseguro)" sem precisar obter e instalar o certificado personalizado da CA (server_rootCA.pem). Em outras palavras - ter que desativar o HSTS permitirá que seu site seja visto publicamente através de HTTP e / ou conexão HTTPS insegura (cuidado!).

Para o Apache2, adicione o seguinte ao arquivo do site, seção HTTP (porta 80)

Header unset Strict-Transport-Security
Header always set Strict-Transport-Security "max-age=0;includeSubDomains"

Testado no Debian / Apache2.4 + Debian / Chromium 59

link

    
por 10.08.2017 / 02:53
4

Existem várias respostas excelentes que dão exemplos de como fazer isso funcionar mas nenhum que explique onde as coisas deram errado em sua tentativa. O OpenSSL pode ser bastante não-intuitivo algumas vezes por isso vale a pena percorrer.

Primeiro, como um aparte, o OpenSSL usa como padrão ignorar qualquer valor de nome distinto você fornece na configuração. Se você quiser usá-los, você deve adicionar prompt = no para sua configuração. Além disso, o comando conforme escrito gera apenas um certificado pedido não é um certificado, por isso o comando -days não faz nada.

Se você gerar sua solicitação de certificado usando este comando, você deu e inspecionou o resultado, o assunto Alt Name está presente:

$ openssl req -new -key server.key -out server.csr -config config.cnf -sha256
$ openssl req -text -noout -in server.csr
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name:
                DNS:dev.mycompany.com
    Signature Algorithm: sha256WithRSAEncryption
         ...

Mas se você gerar o certificado usando o comando no link heroku e inspecione o resultado, o Assunto Alt Name está faltando:

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
$ openssl x509 -text -noout -in server.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            89:fd:75:26:43:08:04:61
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Validity
            Not Before: Jan 21 04:27:21 2018 GMT
            Not After : Jan 21 04:27:21 2019 GMT
        Subject: C = US, ST = Massachusetts, L = Boston, O = MyCompany
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         ...

O motivo é que, por padrão, o OpenSSL não copia extensões da solicitação para o certificado. Normalmente, o certificado seria criado / assinado por um CA com base em uma solicitação de um cliente, e algumas extensões podem conceder certificado mais poder do que a CA estava pretendendo se eles confiassem cegamente as extensões definidas na solicitação.

Existem maneiras de dizer ao OpenSSL para copiar as extensões, mas o IMHO é mais trabalho do que apenas fornecer as extensões em um arquivo de configuração quando você gerar o certificado.

Se você tentasse usar seu arquivo de configuração existente, ele não funcionaria porque a seção de nível superior está marcada com [req] , então essas configurações se aplicam apenas ao comando req e não ao comando x509. Não é necessário ter um marcador de seção de nível superior, portanto, basta remover essa primeira linha e, em seguida, funcionará bem para as solicitações de geração ou para o certificado.

$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt -extfile config.cnf

Como alternativa, você pode usar o argumento -x509 para o comando req para gerar um certificado autoassinado em um único comando, em vez de criar primeiro um pedido e, em seguida, um certificado. Neste caso, não é necessário remover o [req] linha de seção, como essa seção é lida e usada pelo comando req.

$ openssl req -x509 -sha256 -days 365 -key server.key -out server.crt -config config.cnf

Para recapitular, aqui está o arquivo de configuração modificado usado nos comandos acima:

default_bits        = 2048
distinguished_name  = dn
x509_extensions     = san
req_extensions      = san
extensions          = san
prompt              = no
[ dn ]
countryName         = US
stateOrProvinceName = Massachusetts
localityName        = Boston
organizationName    = MyCompany
[ san ]
subjectAltName      = DNS:dev.mycompany.com
    
por 02.02.2018 / 02:28
2

Minha solução é manter o openssl.cnf principal como ele é e, ao final, adicionar uma nova seção como [ cert_www.example.com ] , em que www.example.com é o site para o qual desejo criar um certificado e, em coloque o subjectAltName que eu precisaria (e qualquer outra coisa). Claro que a seção poderia ser chamada como você quiser.

Depois disso, posso executar o comando openssl req como antes, adicionando apenas -extensions cert_www.example.com para seu conteúdo ser selecionado e adicionar -subj para adicionar diretamente todas as informações de DN.

Não se esqueça de verificar o conteúdo do certificado após sua criação e antes de usá-lo, com openssl x509 -text

    
por 24.04.2017 / 00:36
1

Script bash com configuração assada em

Como um script de shell que deve funcionar em plataformas com o bash. Assume HOSTNAME env definido para o shell ou fornece um nome de host de sua escolha, por exemplo, self_signed_cert.sh test

set -e

if [ -z "$1" ]; then
  hostname="$HOSTNAME"
else
  hostname="$1"
fi

local_openssl_config="
[ req ]
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = san_self_signed
[ req_distinguished_name ]
CN=$hostname
[ san_self_signed ]
subjectAltName = DNS:$hostname, DNS:localhost
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = CA:true
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyCertSign, cRLSign
extendedKeyUsage = serverAuth, clientAuth, timeStamping
"

openssl req \
  -newkey rsa:2048 -nodes \
  -keyout "$hostname.key.pem" \
  -x509 -sha256 -days 3650 \
  -config <(echo "$local_openssl_config") \
  -out "$hostname.cert.pem"
openssl x509 -noout -text -in "$hostname.cert.pem"

O acima, mais ou menos, injeta as informações básicas do arquivo de configuração.

Note, incluiu DNS:localhost extra como SAN para permitir testes via localhost mais facilmente. Remova esse bit extra do script se você não quiser.

Crédito

a resposta do bcardarella é ótima (não é possível comentar / votar devido à repetição insuficiente). No entanto, a resposta usa um local de arquivo de configuração openssl existente que é específico da plataforma ... portanto:

Works for me

Obviamente, basta encontrar o arquivo de configuração openssl para sua própria plataforma e substituir o local correto.

Teste

Para uma forma de testar, importe test.cert.pem para as autoridades do chrome em chrome://settings/certificates e:

openssl s_server -key test.key.pem -cert test.cert.pem -accept 20443 -www &
openssl_pid=$!
google-chrome https://localhost:20443

E depois do teste

kill $openssl_pid
    
por 28.08.2017 / 16:32