OpenSSL

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Boîte à outils cryptographique (SSL/TLS, clés, certificats)
Version cible OpenSSL 3.x
Commande openssl
Voir aussi TLS · Ciphers · Gpg

Présentation

OpenSSL est une boîte à outils cryptographique implémentant les protocoles SSL/TLS. Elle fournit :

  • une bibliothèque C pour réaliser des applications client/serveur sécurisées,
  • une commande en ligne (openssl) permettant :
    • la génération de clés RSA, EC, Ed25519,
    • la création de demandes (CSR) et de certificats X.509,
    • le calcul d'empreintes (SHA-256, SHA-512, ...),
    • le chiffrement/déchiffrement symétrique (AES) et asymétrique,
    • la mise en place d'une autorité de certification (CA) et de listes de révocation (CRL),
    • les tests de clients et serveurs TLS,
    • la signature et le chiffrement de courriels (S/MIME, CMS).

Cette page cible OpenSSL 3.x (Debian 12+, Ubuntu 22.04+, RHEL 9+). Les sous-commandes historiques (rsautl, genrsa seul, -ssl3, RC4/DES) sont remplacées par leurs équivalents modernes (pkeyutl, genpkey, TLS 1.2/1.3, AES).

Vocabulaire

  • CA (Certificate Authority) : autorité qui signe les certificats.
  • CSR (Certificate Signing Request) : demande de signature, contient la clé publique + les attributs (sujet, SAN).
  • X.509 : format standard du certificat.
  • SAN (Subject Alternative Name) : liste des noms (DNS/IP) couverts par le certificat. Obligatoire aujourd'hui — le seul CN est ignoré par les navigateurs.
  • PEM : encodage texte base64 (-----BEGIN ...-----). DER : encodage binaire.
  • PKCS#8 : format de clé privée. PKCS#12 / PFX : conteneur (clé + certificats) protégé par mot de passe.

Génération de clés

RSA

  • Clé RSA 4096 bits (méthode moderne genpkey) :
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out server.key
  • Clé RSA chiffrée par mot de passe (demandé à chaque usage) :
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -aes256 -out server.key
chmod 400 server.key

EC (courbes elliptiques)

  • Courbe P-256 (recommandée, équivalent ~3072 bits RSA, beaucoup plus légère) :
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out server.key
  • Courbe P-384 :
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-384 -out server.key

Ed25519

  • Clé de signature moderne (SSH, JWT, etc.) :
openssl genpkey -algorithm ED25519 -out server.key

Opérations sur les clés

  • Extraire la clé publique :
openssl pkey -in server.key -pubout -out server.pub
  • Visualiser une clé (RSA ou EC) :
openssl pkey -in server.key -text -noout
  • Retirer la passphrase d'une clé privée :
openssl pkey -in enc.key -out plain.key
  • Ajouter/changer une passphrase :
openssl pkey -in plain.key -aes256 -out enc.key

Demande de certificat (CSR)

La sous-commande req crée la CSR. Penser à inclure les SAN.

  • Générer une CSR à partir d'une clé existante :
openssl req -new -key server.key -out server.csr \
  -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Nexiat/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com,IP:10.0.0.10"
  • Générer la clé et la CSR en une seule commande (-nodes = clé non chiffrée) :
openssl req -new -newkey rsa:4096 -nodes -keyout server.key -out server.csr \
  -subj "/C=FR/ST=Occitanie/L=Toulouse/O=Nexiat/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:www.example.com"
  • Idem avec une clé EC :
openssl req -new -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes \
  -keyout server.key -out server.csr \
  -subj "/C=FR/O=Nexiat/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com"
  • Visualiser et vérifier une CSR :
openssl req -in server.csr -noout -text -verify

Certificat auto-signé

Utile pour les tests, le dev, ou les services internes sans CA.

  • En une commande (clé + certificat auto-signé avec SAN) :
openssl req -x509 -newkey rsa:4096 -nodes -keyout server.key -out server.crt \
  -days 365 -sha256 \
  -subj "/C=FR/O=Nexiat/CN=server.example.com" \
  -addext "subjectAltName=DNS:server.example.com,DNS:localhost,IP:127.0.0.1"
  • Auto-signer à partir d'une CSR existante (en recopiant ses extensions, dont les SAN) :
openssl x509 -req -in server.csr -signkey server.key -out server.crt \
  -days 365 -sha256 -copy_extensions copyall

Autorité de Certification (CA)

Méthode simple : x509 -CA

Suffisant pour un homelab, des certificats internes ou une CI. Pas de base de données ni de gestion de révocation.

  • Créer la clé de la CA (chiffrée) :
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -aes256 -out ca.key
  • Créer le certificat racine auto-signé de la CA :
openssl req -x509 -new -key ca.key -sha256 -days 3650 -out ca.crt \
  -subj "/C=FR/O=Nexiat/CN=Nexiat Root CA" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign"
  • Signer une CSR avec cette CA.
Les SAN ne sont pas recopiés par défaut. Deux solutions :
(a) recopier les extensions de la CSR (OpenSSL 3.0+) :
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 -sha256 -copy_extensions copyall
(b) fournir un fichier d'extensions ext.cnf :
# ext.cnf
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = DNS:server.example.com, DNS:www.example.com
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 -sha256 -extfile ext.cnf

Méthode complète : openssl ca

Avec base de données (index.txt), numérotation de série, et gestion des CRL. C'est l'approche à utiliser pour une vraie PKI interne.

  • Arborescence et fichiers d'amorçage :
mkdir -p /etc/ssl/nexiat-ca/{certs,crl,newcerts,private,csr}
cd /etc/ssl/nexiat-ca
chmod 700 private
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber
  • Fichier de configuration openssl.cnf :
[ ca ]
default_ca = CA_default

[ CA_default ]
dir               = /etc/ssl/nexiat-ca
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
private_key       = $dir/private/ca.key
certificate       = $dir/certs/ca.crt
crlnumber         = $dir/crlnumber
crl               = $dir/crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30
default_md        = sha256
name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict
# Recopie les SAN portés par la CSR (voir note de sécurité plus bas)
copy_extensions   = copy

[ policy_strict ]
countryName             = match
stateOrProvinceName     = optional
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional

[ req ]
default_bits        = 4096
distinguished_name  = req_distinguished_name
string_mask         = utf8only
default_md          = sha256
x509_extensions     = v3_ca

[ req_distinguished_name ]
countryName                = Country Name (2 letter code)
stateOrProvinceName        = State or Province Name
localityName               = Locality Name
0.organizationName         = Organization Name
organizationalUnitName     = Organizational Unit Name
commonName                 = Common Name

[ v3_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints       = critical, CA:true
keyUsage               = critical, digitalSignature, cRLSign, keyCertSign

[ v3_intermediate_ca ]
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints       = critical, CA:true, pathlen:0
keyUsage               = critical, digitalSignature, cRLSign, keyCertSign

[ server_cert ]
basicConstraints       = CA:FALSE
keyUsage               = critical, digitalSignature, keyEncipherment
extendedKeyUsage       = serverAuth
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always

[ crl_ext ]
authorityKeyIdentifier = keyid:always
  • Créer le certificat racine de la CA (auto-signé) :
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -aes256 -out private/ca.key
openssl req -config openssl.cnf -x509 -new -key private/ca.key \
  -extensions v3_ca -days 3650 -sha256 -out certs/ca.crt \
  -subj "/C=FR/O=Nexiat/CN=Nexiat Root CA"
  • Signer une CSR (certificat serveur) :
openssl ca -config openssl.cnf -extensions server_cert \
  -days 375 -notext -md sha256 -in csr/server.csr -out certs/server.crt
  • Révoquer un certificat :
openssl ca -config openssl.cnf -revoke certs/server.crt
  • Générer la liste de révocation (CRL) :
openssl ca -config openssl.cnf -gencrl -out crl/ca.crl.pem
  • Visualiser une CRL :
openssl crl -in crl/ca.crl.pem -noout -text
Note de sécuritécopy_extensions = copy recopie les extensions de la CSR, y compris potentiellement basicConstraints=CA:TRUE. Comme la section [ server_cert ] force CA:FALSE, le risque est neutralisé pour les certificats serveur. Si tu ne veux pas recopier, supprime cette ligne et déclare les SAN via une section [ alt_names ] référencée dans [ server_cert ].

Inspection et vérification

  • Afficher un certificat en clair :
openssl x509 -in server.crt -noout -text
  • Champs ciblés (sujet, émetteur, dates, série, empreinte) :
openssl x509 -in server.crt -noout -subject -issuer -dates -serial -fingerprint -sha256
  • Vérifier une chaîne de confiance :
openssl verify -CAfile ca.crt server.crt
  • Avec un intermédiaire :
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
  • Vérifier l'expiration (utile pour le monitoring / cert-manager) — code retour 0 si le certificat est encore valide au-delà du délai (ici 30 jours = 2592000 s) :
openssl x509 -checkend 2592000 -noout -in server.crt && echo "OK" || echo "À renouveler"

Correspondance clé / certificat / CSR

Méthode moderne (fonctionne pour RSA et EC) : les trois empreintes de clé publique doivent être identiques.

openssl pkey -in server.key -pubout    | sha256sum
openssl x509 -in server.crt -pubkey -noout | sha256sum
openssl req  -in server.csr -pubkey -noout | sha256sum

Conversions de format

  • DER → PEM :
openssl x509 -inform der -in server.der -out server.pem
  • PEM → DER :
openssl x509 -outform der -in server.pem -out server.der
  • Convertir une clé privée en PKCS#8 :
openssl pkcs8 -topk8 -in server.key -out server.pk8 -nocrypt

PKCS#12 / PFX

  • Créer un conteneur (clé + certificat + chaîne) :
openssl pkcs12 -export -out bundle.p12 -inkey server.key -in server.crt -certfile ca.crt
  • Extraire tout en PEM (clé non chiffrée) :
openssl pkcs12 -in bundle.p12 -out bundle.pem -nodes
  • Extraire uniquement le certificat :
openssl pkcs12 -in bundle.p12 -nokeys -out server.crt
  • Extraire uniquement la clé :
openssl pkcs12 -in bundle.p12 -nocerts -nodes -out server.key
OpenSSL 3.x — pour ouvrir un .p12 ancien chiffré avec des algos obsolètes (RC2-40...), ajouter -legacy :
openssl pkcs12 -legacy -in vieux.p12 -out bundle.pem -nodes

Tests TLS (s_client)

  • Connexion avec SNI (indispensable en vhost / Ingress) :
openssl s_client -connect host.example.com:443 -servername host.example.com
  • Afficher toute la chaîne présentée par le serveur :
openssl s_client -connect host:443 -servername host -showcerts
  • Forcer une version de protocole :
openssl s_client -connect host:443 -tls1_2
openssl s_client -connect host:443 -tls1_3
  • Lire les dates d'expiration d'un service distant (one-liner pratique) :
echo | openssl s_client -connect host:443 -servername host 2>/dev/null \
  | openssl x509 -noout -dates -subject
  • Débogage (messages bruts, fin de session) :
openssl s_client -connect host:443 -servername host -msg -prexit
  • STARTTLS (SMTP, IMAP, etc.) :
openssl s_client -connect mail.example.com:587 -starttls smtp
  • Lister les suites de chiffrement disponibles :
openssl ciphers -v 'HIGH:!aNULL:!MD5'

Empreintes (hash)

  • Empreinte d'un fichier :
openssl dgst -sha256 fichier.bin
openssl sha256 fichier.bin
  • Empreinte SHA-512 :
openssl dgst -sha512 fichier.bin
  • Empreinte d'un certificat :
openssl x509 -in server.crt -noout -fingerprint -sha256

Chiffrement symétrique (enc)

Toujours utiliser un KDF fort (-pbkdf2) — l'ancien dérivé de clé par défaut est faible.

  • Chiffrer un fichier en AES-256-CBC :
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -salt -in clair.txt -out chiffre.enc
  • Déchiffrer :
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -d -in chiffre.enc -out clair.txt
  • Avec armure base64 (-a) :
openssl enc -aes-256-cbc -pbkdf2 -iter 100000 -a -salt -in clair.txt -out chiffre.b64

base64

openssl base64 -in clair.txt -out clair.b64
openssl base64 -d -in clair.b64 -out clair.txt

Chiffrement et signature asymétriques (pkeyutl)

rsautl est déprécié : utiliser pkeyutl.

Chiffrement RSA

RSA ne chiffre que de petites données (< taille de clé). En pratique, on chiffre une clé symétrique aléatoire avec RSA, puis les données avec AES (chiffrement « enveloppe »).
  • Chiffrer (padding OAEP recommandé) :
openssl pkeyutl -encrypt -pubin -inkey server.pub -in clair.txt -out chiffre.dat \
  -pkeyopt rsa_padding_mode:oaep
  • Déchiffrer :
openssl pkeyutl -decrypt -inkey server.key -in chiffre.dat -out clair.txt \
  -pkeyopt rsa_padding_mode:oaep

Signature

  • Signer un fichier (empreinte SHA-256 signée) :
openssl dgst -sha256 -sign server.key -out fichier.sig fichier.txt
  • Vérifier la signature :
openssl dgst -sha256 -verify server.pub -signature fichier.sig fichier.txt

Courriel signé / chiffré (S/MIME)

Pour les nouveaux usages, openssl cms est le successeur de smime (mêmes options, format CMS plus récent).
  • Signer :
openssl smime -sign -in message.txt -signer cert.pem -inkey cle.pem -out signe.eml
  • Vérifier :
openssl smime -verify -in signe.eml -CAfile ca.pem
  • Chiffrer (AES-256) :
openssl smime -encrypt -aes256 -in message.txt -out chiffre.eml destinataire.pem
  • Déchiffrer :
openssl smime -decrypt -in chiffre.eml -recip cert.pem -inkey cle.pem

Notes

https://docs.openssl.org/master/man1/openssl/
https://www.feistyduck.com/library/openssl-cookbook/

Voir aussi