Message → Algorithme → Clé → Texte chiffré → Algorithme → Clé → Message original
Chiffrement de César : Technique de chiffrement par substitution où chaque lettre est décalée de n positions dans l'alphabet.
- Identifier le message à chiffrer
- Déterminer la clé de décalage
- Appliquer le décalage à chaque caractère
- Conserver les caractères non alphabétiques
- Message original (clair)
- Clé de décalage (n)
- Alphabet de substitution
- Message chiffré
Identifier les caractères à chiffrer et les positions dans l'alphabet.
Pour chaque lettre, calculer la nouvelle position : (position + clé) % 26.
Préserver la casse des lettres lors du chiffrement.
def chiffrement_cesar(texte, cle):
resultat = ""
for caractere in texte:
if caractere.isalpha():
# Déterminer si c'est majuscule ou minuscule
base = ord('A') if caractere.isupper() else ord('a')
# Chiffrer la lettre
lettre_chiffree = chr((ord(caractere) - base + cle) % 26 + base)
resultat += lettre_chiffree
else:
# Conserver les caractères non alphabétiques
resultat += caractere
return resultat
def dechiffrement_cesar(texte, cle):
# Inverse du chiffrement
return chiffrement_cesar(texte, -cle)
# Exemple d'utilisation
message = "Bonjour le monde!"
cle = 3
message_chiffre = chiffrement_cesar(message, cle)
message_dechiffre = dechiffrement_cesar(message_chiffre, cle)
print(f"Message original: {message}")
print(f"Message chiffré: {message_chiffre}")
print(f"Message déchiffré: {message_dechiffre}")
• Loi du décalage : Chaque lettre est décalée de n positions
• Principe de modularité : Utilisation de modulo 26 pour les 26 lettres
• Synergie alphabétique : Le chiffrement préserve la structure du message
Chiffrement asymétrique : Système utilisant une paire de clés (publique/privée) pour le chiffrement/déchiffrement.
- Clé publique pour le chiffrement
- Clé privée pour le déchiffrement
- Impossible de déduire la clé privée de la clé publique
- Basé sur des problèmes mathématiques complexes
def generer_cles_rsa():
# Choix de nombres premiers (pour exemple simple)
p, q = 61, 53
n = p * q
phi = (p-1) * (q-1)
# Choix de l'exposant de chiffrement
e = 17 # Doit être copremier avec phi
# Calcul de l'exposant de déchiffrement
d = inverse_modulaire(e, phi)
return (e, n), (d, n) # clé publique, clé privée
def chiffrer_rsa(message, cle_publique):
e, n = cle_publique
# Conversion du message en entiers
message_int = [ord(char) for char in message]
# Chiffrement de chaque caractère
chiffre = [pow(char, e, n) for char in message_int]
return chiffre
def dechiffrer_rsa(chiffre, cle_privee):
d, n = cle_privee
# Déchiffrement de chaque entier
message_int = [pow(c, d, n) for c in chiffre]
# Conversion en chaîne de caractères
message = ''.join(chr(char) for char in message_int)
return message
def pgcd(a, b):
"""Calcul du PGCD"""
while b:
a, b = b, a % b
return a
def inverse_modulaire(a, m):
"""Calcul de l'inverse modulaire"""
if pgcd(a, m) != 1:
return None
for x in range(1, m):
if (a * x) % m == 1:
return x
return None
def generer_cles_rsa():
"""Génération d'une paire de clés RSA (simplifié)"""
# Nombres premiers choisis (en pratique, beaucoup plus grands)
p, q = 61, 53
n = p * q
phi = (p - 1) * (q - 1)
# Choix de e (doit être copremier avec phi)
e = 17
# Calcul de d (inverse modulaire de e modulo phi)
d = inverse_modulaire(e, phi)
cle_publique = (e, n)
cle_privee = (d, n)
return cle_publique, cle_privee
def chiffrer_rsa(message, cle_publique):
"""Chiffrement RSA"""
e, n = cle_publique
message_int = [ord(char) for char in message]
chiffre = [pow(char, e, n) for char in message_int]
return chiffre
def dechiffrer_rsa(chiffre, cle_privee):
"""Déchiffrement RSA"""
d, n = cle_privee
message_int = [pow(c, d, n) for c in chiffre]
message = ''.join(chr(char) for char in message_int)
return message
# Exemple d'utilisation
cle_publique, cle_privee = generer_cles_rsa()
message = "Hello World"
chiffre = chiffrer_rsa(message, cle_publique)
dechiffre = dechiffrer_rsa(chiffre, cle_privee)
print(f"Message original: {message}")
print(f"Message chiffré: {chiffre}")
print(f"Message déchiffré: {dechiffre}")
• Principe de la paire de clés : Une clé pour chiffrer, une autre pour déchiffrer
• Difficulté de calcul inverse : Impossible de déduire la clé privée de la publique
• Base mathématique : Utilisation de problèmes mathématiques complexes
Sécurité cryptographique : Capacité d'un algorithme à résister aux attaques visant à déchiffrer sans la clé.
- Attaque par force brute
- Attaque par analyse fréquentielle
- Attaque par texte chiffré connu
- Attaque par texte clair connu
Évaluer le nombre de tentatives nécessaires pour casser le chiffrement.
Tester la robustesse face aux différentes méthodes d'attaque.
Comparer la sécurité des algorithmes selon leur complexité.
def analyser_securite_algorithme(algorithme, longueur_cle):
"""Analyse de la sécurité d'un algorithme de chiffrement"""
# Calcul du nombre de combinaisons possibles
if algorithme == "cesar":
# 26 possibilités pour le chiffrement de César
combinaisons = 26
nom_algorithme = "Chiffrement de César"
description = "Très faible sécurité, cassable en quelques secondes"
elif algorithme == "vigenere":
# Approximation pour une clé de longueur donnée
combinaisons = 26 ** longueur_cle
nom_algorithme = "Chiffrement de Vigenère"
description = f"Sécurité moyenne pour une clé de {longueur_cle} caractères"
elif algorithme == "rsa":
# Pour RSA, la sécurité dépend de la longueur de la clé
combinaisons = 2 ** longueur_cle
nom_algorithme = f"RSA ({longueur_cle}-bits)"
description = f"Sécurité élevée pour une clé de {longueur_cle} bits"
else:
return "Algorithme inconnu"
# Temps estimé pour casser (hypothétique)
taux_tentatives_par_seconde = 1000000 # 1 million de tentatives/s
temps_secondes = combinaisons / taux_tentatives_par_seconde
if temps_secondes < 1:
temps = "moins d'une seconde"
elif temps_secondes < 60:
temps = f"{temps_secondes:.1f} secondes"
elif temps_secondes < 3600:
temps = f"{temps_secondes/60:.1f} minutes"
elif temps_secondes < 86400:
temps = f"{temps_secondes/3600:.1f} heures"
elif temps_secondes < 31536000:
temps = f"{temps_secondes/86400:.1f} jours"
else:
temps = f"{temps_secondes/31536000:.1f} années"
return f"{nom_algorithme}:\n- Combinaisons: {combinaisons}\n- Temps de cassage estimé: {temps}\n- Description: {description}"
# Comparaison des algorithmes
print(analyser_securite_algorithme("cesar", 1))
print("\n" + analyser_securite_algorithme("vigenere", 5))
print("\n" + analyser_securite_algorithme("rsa", 2048))
• Loi de la complexité : Plus l'espace de clés est grand, plus l'algorithme est sûr
• Principe de Kerckhoffs : La sécurité repose sur la clé, pas sur l'algorithme
• Synergie de la longueur : Des clés plus longues augmentent la sécurité
Algorithmes de hachage : Fonctions qui transforment des données en une chaîne de longueur fixe, résistant aux collisions.
- Unidirectionnel (impossible de retrouver les données)
- Résistant aux collisions
- Calcul rapide mais lent pour le brute-force
- Utilisation de sel (salt) pour renforcer la sécurité
import hashlib
def calculer_hachage(message, algorithme='sha256'):
"""Calcule le hachage d'un message"""
hacheur = hashlib.new(algorithme)
hacheur.update(message.encode())
return hacheur.hexdigest()
def comparer_hachages(message):
"""Compare différents algorithmes de hachage"""
resultats = {}
algorithmes = ['md5', 'sha1', 'sha256', 'sha512']
for algo in algorithmes:
resultats[algo] = calculer_hachage(message, algo)
return resultats
def tester_collision(algorithme, message1, message2):
"""Teste si deux messages produisent la même empreinte"""
hache1 = calculer_hachage(message1, algorithme)
hache2 = calculer_hachage(message2, algorithme)
return hache1 == hache2
import hashlib
import time
class ComparaisonHachage:
def __init__(self):
self.algorithmes = ['md5', 'sha1', 'sha256', 'sha512']
def calculer_hachage(self, message, algorithme='sha256'):
"""Calcule le hachage d'un message"""
try:
hacheur = hashlib.new(algorithme)
hacheur.update(message.encode())
return hacheur.hexdigest()
except ValueError:
return f"Algorithme {algorithme} non supporté"
def comparer_algorithmes(self, message):
"""Compare les hachages produits par différents algorithmes"""
resultats = {}
for algo in self.algorithmes:
debut = time.time()
hache = self.calculer_hachage(message, algo)
temps_execution = time.time() - debut
resultats[algo] = {
'hache': hache,
'temps': temps_execution,
'longueur': len(hache)
}
return resultats
def afficher_resultats(self, message):
"""Affiche les résultats de comparaison"""
print(f"Message: {message}")
print("-" * 60)
resultats = self.comparer_algorithmes(message)
for algo, info in resultats.items():
print(f"{algo.upper()}:")
print(f" Haché: {info['hache']}")
print(f" Longueur: {info['longueur']} caractères")
print(f" Temps: {info['temps']:.6f}s")
print()
def tester_resistance_collision(self):
"""Teste la résistance aux collisions"""
messages = [
"Bonjour",
"bonjour", # Changement de casse
"Bonjour!", # Ajout de caractère
"Bonjour le monde!" # Message plus long
]
print("Tests de résistance aux collisions:")
print("-" * 40)
for algo in self.algorithmes:
print(f"\n{algo.upper()}:")
haches = [self.calculer_hachage(msg, algo) for msg in messages]
# Vérifier les collisions
collisions = set()
for i in range(len(haches)):
for j in range(i+1, len(haches)):
if haches[i] == haches[j]:
collisions.add((messages[i], messages[j]))
if collisions:
print(f" Collisions détectées: {collisions}")
else:
print(f" Aucune collision détectée")
# Exemple d'utilisation
comparaison = ComparaisonHachage()
comparaison.afficher_resultats("Mot de passe secret")
comparaison.tester_resistance_collision()
• Loi de l'unidirectionalité : Le hachage est irréversible
• Principe de la résistance : Des entrées différentes doivent produire des sorties différentes
• Synergie de la complexité : SHA-256 est plus sécurisé que MD5
Protocoles de sécurité : Ensembles de règles et de procédures pour sécuriser la transmission de données.
- SSL/TLS (HTTPS)
- SSH (Secure Shell)
- IPSec (Internet Protocol Security)
- WPA/WPA2 (Wi-Fi Protected Access)
# Simulation d'échange de clés (simplifié)
def echanger_cles():
"""Simule l'échange de clés pour une session sécurisée"""
# Génération de clés (simplifié)
cle_session = "clé_secrete_generee"
return cle_session
def chiffrer_transmission(donnees, cle_session):
"""Chiffre les données avant transmission"""
# Utilisation d'un algorithme de chiffrement symétrique (simplifié)
import base64
donnees_bytes = donnees.encode()
donnees_chiffrees = base64.b64encode(donnees_bytes)
return donnees_chiffrees.decode()
def transmettre_securise(donnees, cle_session):
"""Transmet des données de manière sécurisée"""
donnees_chiffrees = chiffrer_transmission(donnees, cle_session)
# Simulation d'envoi sur un canal sécurisé
print(f"Données transmises: {donnees_chiffrees}")
return donnees_chiffrees
import ssl
import socket
import hashlib
import hmac
class ProtocoleSecurise:
def __init__(self):
self.etat_connexion = "non_connecte"
self.cle_session = None
self.algorithme_hachage = "sha256"
def etablir_connexion_securisee(self, hote, port):
"""Établit une connexion sécurisée avec SSL/TLS"""
try:
# Création d'une socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enveloppement avec SSL
contexte_ssl = ssl.create_default_context()
contexte_ssl.check_hostname = False
contexte_ssl.verify_mode = ssl.CERT_NONE
sock_ssl = contexte_ssl.wrap_socket(sock, server_hostname=hote)
sock_ssl.connect((hote, port))
self.etat_connexion = "connecte"
print(f"Connexion sécurisée établie avec {hote}:{port}")
# Génération de clé de session
self.generer_cle_session()
return sock_ssl
except Exception as e:
print(f"Erreur de connexion : {e}")
return None
def generer_cle_session(self):
"""Génère une clé de session pour la communication"""
import secrets
self.cle_session = secrets.token_bytes(32) # 256 bits
print("Clé de session générée")
def chiffrer_message(self, message):
"""Chiffre un message avec HMAC pour l'authentification"""
message_bytes = message.encode()
hache_mac = hmac.new(self.cle_session, message_bytes, hashlib.sha256).hexdigest()
message_chiffre = message_bytes.hex() + hache_mac
return message_chiffre
def dechiffrer_message(self, message_chiffre):
"""Déchiffre un message et vérifie l'authenticité"""
# Extraction de la signature HMAC
longueur_hache = 64 # SHA-256 = 256 bits = 64 caractères hex
message_hex = message_chiffre[:-longueur_hache]
hache_recu = message_chiffre[-longueur_hache:]
# Conversion en bytes
message_bytes = bytes.fromhex(message_hex)
# Vérification de l'authenticité
hache_calcule = hmac.new(self.cle_session, message_bytes, hashlib.sha256).hexdigest()
if hache_calcule == hache_recu:
return message_bytes.decode(), True
else:
return "", False
def envoyer_message(self, socket_ssl, message):
"""Envoie un message chiffré via la connexion sécurisée"""
message_chiffre = self.chiffrer_message(message)
socket_ssl.send(message_chiffre.encode())
print(f"Message envoyé: {message_chiffre[:20]}...")
def recevoir_message(self, socket_ssl):
"""Reçoit et déchiffre un message via la connexion sécurisée"""
message_chiffre = socket_ssl.recv(1024).decode()
message, authentique = self.dechiffrer_message(message_chiffre)
if authentique:
print(f"Message reçu: {message}")
return message
else:
print("Message non authentique - potentiellement compromis")
return ""
# Exemple d'utilisation (simulation)
protocole = ProtocoleSecurise()
# protocole.etablir_connexion_securisee("exemple.com", 443)
• Loi de la confidentialité : Les données doivent être chiffrées pendant la transmission
• Principe de l'authentification : Vérifier l'identité des parties
• Synergie de la sécurité : SSL/TLS combine chiffrement et authentification
- Symétrique : Même clé pour chiffrer et déchiffrer (AES, DES)
- Asymétrique : Clés différentes pour chiffrer/déchiffrer (RSA, ECC)
- Hachage : Transformation unidirectionnelle (SHA-256, MD5)
- Hybride : Combinaison de plusieurs méthodes
- Quantique : Cryptographie résistante aux ordinateurs quantiques
- Le chiffrement protège les données contre l'accès non autorisé
- Les clés symétriques sont plus rapides mais nécessitent un échange sécurisé
- Les clés asymétriques permettent l'échange de clés sans canal sécurisé
- Les algorithmes de hachage assurent l'intégrité des données
- La sécurité dépend de la longueur des clés et de la complexité de l'algorithme
Cryptographie classique → RSA → AES → Protocoles SSL/TLS → Cryptographie quantique