Question Comment créer un certificat auto-signé avec openssl?


J'ajoute le support https à un périphérique Linux embarqué. J'ai essayé de générer un certificat auto-signé avec ces étapes:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

Cela fonctionne, mais j'ai des erreurs avec, par exemple, google chrome:

Ce n'est probablement pas le site que vous recherchez!
  Le certificat de sécurité du site n'est pas approuvé!

Est-ce que je manque quelque chose? Est-ce la bonne façon de construire un certificat auto-signé?


854
2018-04-16 14:14


origine


Réponses:


Vous pouvez le faire en une seule commande:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

Vous pouvez également ajouter -nodes Si vous ne voulez pas protéger votre clé privée avec un mot de passe, sinon il vous demandera un mot de passe "au moins 4 caractères". Le paramètre days (365) que vous pouvez remplacer par n'importe quel nombre pour affecter la date d'expiration. Il vous demandera ensuite des choses comme «Nom du pays», mais vous pouvez simplement appuyer sur Entrée et accepter les valeurs par défaut.

Ajouter -subj '/CN=localhost' supprimer des questions sur le contenu du certificat (remplacer localhost avec votre domaine désiré)

Les certificats auto-signés ne sont validés avec aucune tierce partie à moins que vous ne les importiez auparavant dans les navigateurs. Si vous avez besoin de plus de sécurité, vous devez utiliser un certificat signé par une autorité de certification.


1485
2018-04-16 15:04



Est-ce que je manque quelque chose? Est-ce la bonne façon de construire un certificat auto-signé?

Il est facile de créer un certificat auto-signé. Vous utilisez simplement le openssl req commander. Il peut être difficile d'en créer un qui peut être utilisé par la plus grande sélection de clients, comme les navigateurs et les outils de ligne de commande.

C'est difficile parce que les navigateurs ont leurs propres exigences, et ils sont plus restrictifs que l'IETF. Les exigences utilisées par les navigateurs sont documentées au Forums CA / Browser (voir les références ci-dessous). Les restrictions surviennent dans deux domaines clés: (1) les ancres de confiance et (2) les noms DNS.

Les navigateurs modernes (comme les warez que nous utilisons en 2014/2015) veulent un certificat qui enchaîne à une ancre de confiance, et ils veulent que les noms DNS soient présentés de manière particulière dans le certificat. Et les navigateurs se déplacent activement contre les certificats de serveur auto-signés

Certains navigateurs ne facilitent pas vraiment l'importation d'un certificat de serveur auto-signé. En fait, vous ne pouvez pas avec certains navigateurs, comme le navigateur Android. Donc la solution complète est de devenir votre propre autorité.

En l'absence de votre propre autorité, vous devez obtenir les noms DNS appropriés pour donner au certificat les meilleures chances de succès. Mais je vous encourage à devenir votre propre autorité. Il est facile de devenir votre propre autorité et il sera à côté de tous les problèmes de confiance (qui de mieux faire confiance que vous-même?).


Ce n'est probablement pas le site que vous recherchez!
  Le certificat de sécurité du site n'est pas approuvé!

En effet, les navigateurs utilisent une liste prédéfinie d'ancres de confiance pour valider les certificats de serveur. Un certificat auto-signé ne renvoie pas à une ancre approuvée.

La meilleure façon d'éviter cela est:

  1. Créez votre propre autorité (par exemple, devenez une autorité de certification)
  2. Créer une demande de signature de certificat (CSR) pour le serveur
  3. Signer la CSR du serveur avec votre clé CA
  4. Installez le certificat de serveur sur le serveur
  5. Installez le certificat CA sur le client

Étape 1 - Créez votre propre autorité signifie simplement créer un certificat auto-signé avec CA: true et l'utilisation correcte des clés. Cela signifie que le sujet et l'émetteur sont la même entité, CA est défini sur true dans les contraintes de base (il doit également être marqué comme critique), l'utilisation des clés est keyCertSign et crlSign (si vous utilisez des CRL), et l'identificateur de clé de sujet (SKI) est le même que l'identificateur de clé d'autorité (AKI).

Pour devenir votre propre autorité de certification, voir Comment signer une demande de signature de certificat avec votre autorité de certification? sur le dépassement de pile. Ensuite, importez votre autorité de certification dans le magasin de confiance utilisé par le navigateur.

Les étapes 2 à 4 sont à peu près ce que vous faites maintenant pour un serveur public lorsque vous faites appel aux services d'un CA comme Startcom ou CAcert. Les étapes 1 et 5 vous permettent d'éviter l'autorité d'un tiers et d'agir en tant que votre propre autorité (qui est-il préférable de faire confiance à vous-même?).

La meilleure façon d'éviter l'avertissement du navigateur est de faire confiance au certificat du serveur. Mais certains navigateurs, comme le navigateur par défaut d'Android, ne vous permettent pas de le faire. Donc ça ne marchera jamais sur la plateforme.

Le problème des navigateurs (et d'autres agents utilisateurs similaires) ne pas La confiance des certificats auto-signés va être un gros problème dans l'Internet des objets (IoT). Par exemple, que se passe-t-il lorsque vous vous connectez à votre thermostat ou à votre réfrigérateur pour le programmer? La réponse est, rien de bon en ce qui concerne l'expérience de l'utilisateur.

Le groupe de travail WebAppSec du W3C commence à s'intéresser au problème. Voir, par exemple, Proposition: Marquage HTTP comme non sécurisé.


Comment créer un certificat auto-signé avec openssl?

Les commandes ci-dessous et le fichier de configuration créent un certificat auto-signé (il vous montre également comment créer une demande de signature). Ils diffèrent des autres réponses sur un point: les noms DNS utilisés pour le certificat auto-signé sont dans le Nom alternatif du sujet (SAN)et pas le Nom commun (CN).

Les noms DNS sont placés dans le SAN via le fichier de configuration avec la ligne subjectAltName = @alternate_names (il n'y a aucun moyen de le faire à travers la ligne de commande). Ensuite, il y a un alternate_names section dans le fichier de configuration (vous devriez régler ceci selon vos goûts):

[ 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

Il est important de mettre le nom DNS dans le SAN et non pas le CN car tous les deux L'IETF et les Forums CA / Browser précisent la pratique. Ils spécifient également que les noms DNS dans le CN sont obsolètes (mais pas interdits). Si vous mettez un nom DNS dans le CN, alors il doit être inclus dans le SAN en vertu des politiques CA / B. Vous ne pouvez donc pas éviter d'utiliser le nom alternatif du sujet.

Si vous ne définissez pas de noms DNS dans le SAN, le certificat ne pourra pas être validé sous un navigateur et d'autres agents utilisateur qui suivent les consignes du forum CA / Browser.

Connexes: les navigateurs suivent les règles du forum CA / Browser. et pas les politiques de l'IETF. C'est l'une des raisons pour lesquelles un certificat créé avec OpenSSL (qui suit généralement l'IETF) ne valide parfois pas sous un navigateur (les navigateurs suivent l'AC / B). Ce sont des normes différentes, elles ont des politiques d'émission différentes et des exigences de validation différentes.


Créer un certificat auto-signé (remarquez l'ajout de -x509 option):

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

Créer une demande de signature (remarquez le manque de -x509 option):

openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
    -keyout example-com.key.pem -days 365 -out example-com.req.pem

Imprimer un certificat auto-signé:

openssl x509 -in example-com.cert.pem -text -noout

Imprimer une demande de signature:

openssl req -in example-com.req.pem -text -noout

Fichier de configuration (transmis via -config option)

[ 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 its 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

Vous devrez peut-être effectuer les opérations suivantes pour Chrome. Autrement Chrome peut se plaindre d'un Nom commun est invalide (ERR_CERT_COMMON_NAME_INVALID). Je ne suis pas sûr de ce que la relation est entre une adresse IP dans le SAN et un CN dans ce cas.

# IPv4 localhost
# IP.1       = 127.0.0.1

# IPv6 localhost
# IP.2     = ::1

Il existe d'autres règles concernant la gestion des noms DNS dans les certificats X.509 / PKIX. Reportez-vous à ces documents pour les règles:

RFC 6797 et RFC 7469 sont répertoriés car ils sont plus restrictifs que les autres documents RFC et CA / B. RFC 6797 et 7469 ne pas autoriser une adresse IP, soit.


390
2018-01-13 21:12



Voici les options décrites dans @ réponse de diegows, décrit plus en détail, de La documentation:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
req

Demande de certificat PKCS # 10 et utilitaire de génération de certificat.

-x509

cette option génère un certificat auto-signé au lieu d'une demande de certificat.   Ceci est généralement utilisé pour générer un certificat de test ou une autorité de certification racine auto-signée.

-newkey arg

cette option crée une nouvelle demande de certificat et une nouvelle clé privée. L'argument   prend l'une de plusieurs formes. rsa: nbits, où nbits est le nombre de bits,   génère une clé RSA nbits en taille.

-keyout filename

cela donne le nom de fichier pour écrire la clé privée nouvellement créée.

-out filename

Cela spécifie le nom de fichier de sortie à écrire ou la sortie standard par défaut.

-days n

quand le -x509 option est utilisée qui spécifie le nombre de jours à certifier   le certificat pour. La valeur par défaut est 30 jours.

-nodes

Si cette option est spécifiée, si une clé privée est créée, elle ne sera pas cryptée.

La documentation est en fait plus détaillée que ce qui précède, je viens de le résumer ici.


353
2018-04-13 01:48



Je ne peux pas commenter, donc je vais mettre cela comme une réponse séparée. J'ai trouvé quelques problèmes avec la réponse d'un interlocuteur acceptée:

  • Le one-liner inclut une phrase secrète dans la clé.
  • Le one-liner utilise SHA1 qui dans de nombreux navigateurs jette des avertissements dans la console.

Voici une version simplifiée qui supprime la phrase secrète, augmente la sécurité pour supprimer les avertissements et inclut une suggestion dans les commentaires pour transmettre -subj pour supprimer la liste complète des questions:

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Remplacez 'localhost' par le domaine dont vous avez besoin. Vous devrez exécuter les deux premières commandes une par une, car openssl vous demandera une phrase secrète.

Pour combiner les deux dans un fichier .pem:

cat server.crt server.key > cert.pem

106
2017-08-13 09:44



La commande suivante:

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -days 3650

crée un certificat pour le domaine example.com C'est

  • relativement fort (à partir de 2018) et
  • valable 3650 jours (~ 10 ans).

Il crée les fichiers suivants:

  • Clé privée: example.key
  • Certificat: example.crt

Comme toutes les informations sont fournies sur la ligne de commande, il n'y a pas d'entrée interactive gênante. De plus, toutes les étapes nécessaires sont exécutées par ce seul appel OpenSSL: de la génération de clé privée jusqu'au certificat auto-signé.

Comme le certificat est auto-signé et doit être accepté manuellement par les utilisateurs, il n'est pas logique d'utiliser une expiration courte ou une crypto faible.

À l'avenir, vous pourriez vouloir utiliser plus de 4096 bits pour la clé RSA et un algorithme de hachage plus fort que sha256, mais à partir de 2018, ce sont des valeurs saines. Ils sont suffisamment forts tout en étant supportés par tous les navigateurs modernes.

Note latérale: Théoriquement, vous pourriez laisser de côté -nodes paramètre (ce qui signifie "pas de cryptage DES"), auquel cas example.key serait crypté avec un mot de passe. Cependant, cela n'est presque jamais utile pour une installation de serveur, car vous devez également stocker le mot de passe sur le serveur, ou vous devez l'entrer manuellement à chaque redémarrage.


105
2017-12-28 17:30



Je recommanderais d'ajouter -sha256 paramètre, pour utiliser l'algorithme de hachage SHA-2, car les principaux navigateurs considèrent que les "certificats SHA-1" ne sont pas sécurisés.

La même ligne de commande à partir de la réponse acceptée - @diegows avec ajouté -sha256

openssl req -x509 -sha256 -newkey rsa: 2048 -keyout key.pem -out cert.pem -jours XXX

Plus d'infos dans Blog Google Security.

Mise à jour mai 2018. Comme indiqué dans les commentaires, l'utilisation de SHA-2 n'ajoute aucune sécurité au certificat auto-signé. Mais je recommande toujours de l'utiliser comme une bonne habitude de ne pas utiliser des fonctions de hachage cryptographiques périmées / non sécurisées. Une explication complète est disponible dans: https://security.stackexchange.com/questions/91913/why-is-it-fine-for-certificates-above-the-end-entity-certificate-to-be-sha1-base


63
2017-10-20 09:52



Les navigateurs modernes lancent maintenant une erreur de sécurité pour les certificats autosignés autrement bien formés s'il leur manque un SAN (Subject Alternate Name). OpenSSL ne fournit pas de moyen de ligne de commande pour spécifier ceci, tant de tutoriels et de signets de développeurs sont soudainement obsolètes.

Le moyen le plus rapide de s'exécuter à nouveau est un fichier conf court et autonome:

  1. Créez un fichier de configuration OpenSSL (exemple: req.cnf)

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
  2. Créez le certificat référençant ce fichier de configuration

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    

Exemple de configuration à partir de https://support.citrix.com/article/CTX135602


53
2018-05-09 02:37



C'est le script que j'utilise sur les boîtes locales pour définir le SAN (subjectAltName) dans les certificats auto-signés.

Ce script prend le nom de domaine (example.com) et génère le SAN pour * .example.com et example.com dans le même certificat. Les sections ci-dessous sont commentées. Nommez le script (par ex. generate-ssl.sh) et lui donner des permissions exécutables. Les fichiers seront écrits dans le même répertoire que le script.

Chrome 58 et ultérieur nécessite que SAN soit défini dans des certificats auto-signés.

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"

Ce script écrit également un fichier d'informations afin que vous puissiez inspecter le nouveau certificat et vérifier que le SAN est correctement défini.

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...

Si vous utilisez Apache, vous pouvez référencer le CERT ci-dessus dans votre fichier de configuration comme ceci:

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>

N'oubliez pas de redémarrer votre serveur Apache (ou Nginx, ou IIS) pour que le nouveau certificat prenne effet.


11
2018-05-13 20:21