Seb-Info

La signature électronique

La signature électronique

Définition

Une signature électronique est un mécanisme cryptographique qui garantit :

  • Authenticité : le message provient bien du signataire.
  • Intégrité : le message n’a pas été modifié.
  • Non-répudiation : le signataire ne peut pas nier avoir signé.

Elle repose sur la cryptographie asymétrique : une clé privée pour signer, une clé publique pour vérifier.

2️⃣ Principe général

Étape 1 – Calcul du haché

On calcule un condensat du message :

H = Hash(message)

Étape 2 – Signature du haché

Le haché est chiffré avec la clé privée du signataire :

S = Chiffrer(H, clé_privée)

Étape 3 – Vérification

  1. Le destinataire déchiffre S avec la clé publique → H'
  2. Il recalcule le haché du message reçu → H
  3. Il compare : si H' = H → la signature est valide ✅
Message → Hachage → Clé privée → Signature
(Message + Signature) → Vérification → Clé publique → OK / NON

3️⃣ Exemple simplifié

Étape Opération Résultat
1 Hachage SHA-256 a3b9…ef2
2 Signature avec clé privée RSA 0x7c2a…d9e
3 Vérification avec clé publique OK

La signature ne chiffre pas le message : elle authentifie son auteur et garantit qu’il n’a pas été modifié.

4️⃣ Signature vs chiffrement

Objectif Clé utilisée But
Chiffrement Clé publique pour chiffrer, clé privée pour déchiffrer Confidentialité
Signature Clé privée pour signer, clé publique pour vérifier Authenticité

5️⃣ Standards et formats

  • Algorithmes : RSA, DSA, ECDSA
  • Fonctions de hachage : SHA-256, SHA-512
  • Certificats : X.509 (clé publique + identité)
  • Formats de signature : PKCS#7, PAdES (PDF), XAdES (XML)

6️⃣ Usages concrets

  • Signature des e-mails (PGP, S/MIME)
  • Signature des logiciels (Microsoft, APK, Linux)
  • Signature de documents PDF ou factures électroniques
  • Authentification TLS (certificats serveurs HTTPS)

À retenir

  • La signature électronique garantit intégrité et authenticité.
  • Elle repose sur une clé privée (signature) et une clé publique (vérification).
  • Elle est au cœur de la sécurité des échanges numériques.

TD – Pratique avec OpenSSL et Python

Objectif

Signer et vérifier un message avec des outils réels (OpenSSL et Python).

Partie 1 – OpenSSL

# 1. Génération des clés RSA
openssl genrsa -out cle_privee.pem 2048
openssl rsa -in cle_privee.pem -pubout -out cle_publique.pem

# 2. Fichier à signer
echo "Message confidentiel" > message.txt

# 3. Signature
openssl dgst -sha256 -sign cle_privee.pem -out signature.bin message.txt

# 4. Vérification
openssl dgst -sha256 -verify cle_publique.pem -signature signature.bin message.txt
# => Verified OK

Exercice : modifier le contenu du fichier message.txt puis relancer la vérification. Que se passe-t-il ? Pourquoi ?

Partie 2 – Python (bibliothèque cryptography)

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding, rsa

# Génération de la paire de clés
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

message = b"Signature test BTS SIO SLAM"

# Signature du message
signature = private_key.sign(
    message,
    padding.PKCS1v15(),
    hashes.SHA256()
)

# Vérification
try:
    public_key.verify(
        signature,
        message,
        padding.PKCS1v15(),
        hashes.SHA256()
    )
    print("Signature valide")
except Exception:
    print("Signature invalide")

Question : que se passe-t-il si vous changez une lettre dans message avant la vérification ?

Outils utilisés : OpenSSL (terminal) et Python cryptography pour visualiser le lien entre théorie et pratique.

Explication : génération et rôle des clés RSA


private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
  

1) Génération de la clé privée

La fonction rsa.generate_private_key() crée une paire de clés RSA :

  • une clé privée, stockée dans private_key ;
  • et implicitement une clé publique, dérivée de la clé privée.

Les deux paramètres sont importants :

  • public_exponent=65537 → valeur standard sûre utilisée dans presque tous les systèmes RSA modernes ;
  • key_size=2048 → taille de clé en bits : 2048 bits est le minimum recommandé pour une bonne sécurité.

Concrètement, Python génère deux grands nombres premiers aléatoires p et q, calcule n = p × q, puis détermine l’exposant public e (ici 65537) et la clé privée d telle que e × d ≡ 1 (mod φ(n)).

2) Extraction de la clé publique

La ligne suivante :

public_key = private_key.public_key()

extrait la clé publique correspondant à la clé privée.
On peut donc dériver la clé publique à partir de la clé privée, mais jamais l’inverse.

Clé Utilisation Confidentialité
private_key Signer ou déchiffrer Doit rester secrète
public_key Vérifier ou chiffrer Peut être diffusée
Génération RSA :
rsa.generate_private_key(…) ───► private_key


public_key = private_key.public_key()
  • La clé privée signe ou déchiffre les messages.
  • La clé publique vérifie ou chiffre les messages.
  • Ensemble, elles assurent authenticité, intégrité et confidentialité.

 

Stockage et réutilisation des clés RSA

Lorsqu’on exécute le code :


private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()
  

les clés existent uniquement en mémoire.
Si vous fermez le programme, elles sont perdues.
Il faut donc les enregistrer dans des fichiers au format PEM pour pouvoir les réutiliser.

🔹 Sauvegarder la clé privée


from cryptography.hazmat.primitives import serialization

with open("cle_privee.pem", "wb") as f:
    f.write(
        private_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()  # Pour TP uniquement
        )
    )
  

Ce fichier cle_privee.pem contient la clé privée RSA.
Ne le partagez jamais : il doit rester strictement confidentiel (comme un mot de passe).

 Sauvegarder la clé publique


with open("cle_publique.pem", "wb") as f:
    f.write(
        public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )
    )
  

Le fichier cle_publique.pem contient la clé publique correspondante.
Vous pouvez le diffuser librement : il servira à vérifier vos signatures.

Structure conseillée

signature_elec/
│
├── cle_privee.pem        ← confidentielle
├── cle_publique.pem      ← partageable
├── message.txt
├── signature.bin
└── signer.py / verifier.py

Charger les clés existantes

Pour réutiliser les clés sauvegardées :


# Charger la clé privée
with open("cle_privee.pem", "rb") as f:
    private_key = serialization.load_pem_private_key(f.read(), password=None)

# Charger la clé publique
with open("cle_publique.pem", "rb") as f:
    public_key = serialization.load_pem_public_key(f.read())
  
  • Clé privée → pour signer ou déchiffrer.
  • Clé publique → pour vérifier ou chiffrer.
  • En production, les clés doivent être protégées par mot de passe ou stockées dans un HSM.

Exemple complet


from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding, rsa

# Génération
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

# Sauvegarde
with open("cle_privee.pem", "wb") as f:
    f.write(private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ))

with open("cle_publique.pem", "wb") as f:
    f.write(public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    ))

print("Clés générées et sauvegardées.")
  

 

Ce contenu est réservé aux membres du site. Si vous êtes un utilisateur existant, veuillez vous connecter. Les nouveaux utilisateurs peuvent s'inscrire ci-dessous.

Connexion pour les utilisateurs enregistrés
   
Nouvel utilisateur ?
*Champ requis
Powered by WP-Members