web-dev-qa-db-fra.com

Génération d'un certificat auto-signé avec openssl qui fonctionne dans Chrome 58

Depuis Chrome 58, il n'accepte plus les certificats auto-signés qui s'appuient sur Common Name: https://productforums.google.com/forum/#!topic/chrome/zVo3M8CgKzQ;context-place=topicsearchin/chrome/category $ 3ACanary% 7Csort: pertinence% 7Cspell: false

Au lieu de cela, il nécessite l'utilisation de Subject Alt Name. J'ai déjà suivi ce guide sur la façon de générer un certificat auto-signé: https://devcenter.heroku.com/articles/ssl-certificate-self qui fonctionnait très bien parce que j'avais besoin du server.crt et server.key fichiers pour ce que je fais. Je dois maintenant générer de nouveaux certificats qui incluent le SAN mais toutes mes tentatives pour le faire n'ont pas fonctionné avec Chrome 58.

Voici ce que j'ai fait:

J'ai suivi les étapes de l'article Heroku mentionné ci-dessus pour générer la clé. J'ai ensuite écrit un nouveau fichier de configuration 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

Puis généré le server.crt avec la commande suivante:

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

Je suis sur un Mac, j'ai donc ouvert le server.crt fichier avec trousseau, l'a ajouté à mes certificats système. Je l'ai ensuite réglé sur Always Trust.

À l'exception du fichier de configuration pour définir la valeur SAN, ce sont des étapes similaires que j'ai utilisées dans les versions précédentes de Chrome pour générer et approuver le certificat auto-signé .

Cependant, après cela, je reçois toujours le ERR_CERT_COMMON_NAME_INVALID in Chrome 58.

54
bcardarella

Ma solution:

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

Statut: Fonctionne pour moi

67
bcardarella

Sous Windows, enregistrez ce script dans votre dossier SSL en tant que makeCERT.bat. Il va créer ces fichiers: 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
17
STWilson

Il y a plusieurs bonnes réponses qui donnent des exemples de comment faire fonctionner cela, mais aucune qui explique où les choses ont mal tourné dans votre tentative. OpenSSL peut parfois être assez non intuitif, donc cela vaut la peine de s'y promener.

Tout d'abord, en passant, OpenSSL par défaut ignore les valeurs de nom distinctif que vous fournissez dans la configuration. Si vous souhaitez les utiliser, vous devez ajouter Prompt = no À votre configuration. De plus, la commande telle qu'elle est écrite ne génère qu'un certificat demande pas un certificat lui-même, donc la commande -days Ne fait rien.

Si vous générez votre demande de certificat à l'aide de cette commande que vous avez donnée et inspectez le résultat, le nom du sujet Alt est présent:

$ 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
         ...

Mais ensuite, si vous générez le certificat à l'aide de la commande dans le lien Heroku et inspectez le résultat, le nom du sujet Alt est manquant:

$ 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
         ...

La raison en est que, par défaut, OpenSSL ne copie pas les extensions de la demande vers le certificat. Normalement, le certificat serait créé/signé par une autorité de certification sur la base d'une demande d'un client, et certaines extensions pourraient accorder au certificat plus de pouvoir que l'autorité de certification si elles devaient faire confiance aveuglément aux extensions définies dans la demande.

Il existe des moyens de dire à OpenSSL de copier les extensions, mais à mon humble avis, c'est plus de travail que de simplement fournir les extensions dans un fichier de configuration lorsque vous générez le certificat.

Si vous tentiez d'utiliser votre fichier de configuration existant, cela ne fonctionnera pas car la section de niveau supérieur est marquée [req], Donc ces paramètres s'appliquent uniquement à la commande req et non à la commande x509. Il n'est pas nécessaire d'avoir un marqueur de section de niveau supérieur, vous pouvez donc simplement supprimer cette première ligne, et cela fonctionnera correctement pour la génération de demandes ou de certificats.

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

Vous pouvez également utiliser l'argument -x509 De la commande req pour générer un certificat auto-signé dans une seule commande, plutôt que de créer d'abord une demande, puis un certificat. Dans ce cas, il n'est pas nécessaire de supprimer la ligne de section [req], Car cette section est lue et utilisée par la commande req.

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

Pour récapituler, voici le fichier de configuration modifié utilisé dans les commandes ci-dessus:

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
13
pavon

Voici une solution qui fonctionne pour moi:

Créer une clé CA et un certificat

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

Créer racine_serveurCA.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

Créer un fichier de configuration v3.ext

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

[alt_names]
DNS.1 = server.berlin

Créer une clé de serveur

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

Créer un certificat de serveur

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

Ajouter un certificat et une clé au fichier de site Apache2, section HTTPS (port 443)

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

Copiez server_rootCA.pem du serveur vers votre machine ..

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

.. et ajoutez-le au navigateur Chromium

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

VOUS ÊTES TOUT FAIT!

P.S. Au lieu de créer une paire de certificats CA et de serveur fonctionnelle (selon les instructions ci-dessus), vous pouvez simplement désactiver les en-têtes HSTS dans votre configuration de serveur HTTP. Cela empêchera Chromium d'appliquer HTTPS et permettra aux utilisateurs de cliquer sur "Avancé → passer à your.url (unsafe)" sans avoir à obtenir et installer votre certificat CA (server_rootCA.pem) personnalisé. En d'autres termes - avoir à désactiver HSTS permettra à votre site d'être affiché publiquement via HTTP et/ou une connexion HTTPS non sécurisée (attention!).

Pour Apache2, ajoutez ce qui suit au fichier de site, section HTTP (port 80)

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

Testé sur Debian/Apache2.4 + Debian/Chromium 59

https://ram.k0a1a.net/self-signed_https_cert_after_chrome_58

13
binary.koala

Ma solution est de garder le principal openssl.cnf comme c'est et juste à la fin pour ajouter une nouvelle section comme [ cert_www.example.com ] où www.example.com est le site Web pour lequel je veux créer un certificat, et y mettre le subjectAltName dont j'aurais besoin (et toute autre chose). Bien sûr, la section peut être nommée comme vous le souhaitez.

Après cela, je peux exécuter le openssl req commande comme précédemment, en ajoutant simplement -extensions cert_www.example.com pour que son contenu soit récupéré et j'ajoute -subj pour ajouter directement toutes les informations DN.

N'oubliez pas de vérifier le contenu du certificat après sa création et avant son utilisation, avec openssl x509 -text

2
Patrick Mevzek

Script bash avec config cuit dans

En tant que script Shell qui devrait fonctionner sur toutes les plateformes avec bash. Suppose que HOSTNAME env est défini pour le shell ou fournit un nom d'hôte de votre choix, par exemple 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"

Ce qui précède injecte plus ou moins le strict minimum nécessaire aux informations du fichier de configuration openssl.

Remarque, inclus extra DNS:localhost en tant que SAN pour permettre les tests via localhost plus facilement. Supprimez ce bit supplémentaire du script si vous ne le souhaitez pas.

Crédit

réponse de bcardarella est super (ne peut pas commenter/voter en raison d'un représentant insuffisant). Cependant, la réponse utilise un emplacement de fichier de configuration openssl existant qui est spécifique à la plate-forme ... d'où:

Travaille pour moi

Évidemment, il suffirait de trouver le fichier de configuration openssl pour votre propre plate-forme donnée et de remplacer l'emplacement correct.

Tester

Pour tester, importez test.cert.pem dans les autorités de chrome dans chrome://settings/certificates, et:

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

Et après les tests

kill $openssl_pid
2
JPvRiel