import tkinter as tk
from tkinter import messagebox
import sqlite3
import hashlib
import sys
# --- 1. CONFIGURATION CRYPTOGRAPHIQUE (Clés de César) ---
# Décalage constant pour le Nom
DECALAGE_NOM = 3
# Décalage constant pour le Login
DECALAGE_LOGIN = 7
CLE_VIGENERE = "SECRETE" # Gardé par prudence mais non utilisé (César est utilisé)
# --- 2. FONCTIONS DE CHIFFREMENT & DÉCHIFFREMENT (César) ---
def chiffrer_cesar(texte, decalage):
"""Chiffre un texte en utilisant le chiffrement de César avec un décalage donné."""
texte = [Link]()
resultat = []
for char in texte:
if 'A' <= char <= 'Z':
char_pos = ord(char) - ord('A')
chiffre_pos = (char_pos + decalage) % 26
[Link](chr(chiffre_pos + ord('A')))
else:
[Link](char)
return "".join(resultat)
def dechiffrer_cesar(texte_chiffre, decalage):
"""Déchiffre un texte chiffré en utilisant le chiffrement de César."""
texte_chiffre = texte_chiffre.upper()
resultat = []
for char in texte_chiffre:
if 'A' <= char <= 'Z':
char_pos = ord(char) - ord('A')
dechiffre_pos = (char_pos - decalage + 26) % 26
[Link](chr(dechiffre_pos + ord('A')))
else:
[Link](char)
return "".join(resultat)
# Hachage SHA-256 (Pour le Mot de Passe)
def hacher_password(password):
return hashlib.sha256([Link]()).hexdigest()
# --- 3. GESTION DE LA BASE DE DONNÉES SQLITE ---
DB_NAME = 'chiffrement_utilisateur_cesar.db'
def configurer_db():
"""Crée la connexion et la table utilisateur si elle n'existe pas."""
conn = [Link](DB_NAME)
cursor = [Link]()
[Link]('''
CREATE TABLE IF NOT EXISTS utilisateur (
iduser INTEGER PRIMARY KEY,
nom_chiffre TEXT, -- Chiffré César (Nom)
login_chiffre TEXT UNIQUE, -- Chiffré César (Login) - Ajout de UNIQUE
password_hash TEXT -- Haché SHA-256
''')
[Link]()
return conn
# --- 4. APPLICATION PRINCIPALE (Affiche après Login) ---
class AppChiffrementCesar([Link]):
def __init__(self, master, conn, username):
super().__init__(master)
[Link]() # Cache la fenêtre de login/accueil
[Link] = conn
[Link](f"Application de Chiffrement/Déchiffrement (César) - Connecté: {username}")
[Link](
"Clés de César",
f"Décalage Nom : {DECALAGE_NOM}\n"
f"Décalage Login : {DECALAGE_LOGIN}"
self.create_widgets()
self.afficher_db()
# ... (Le reste des méthodes create_widgets, enregistrer_utilisateur,
# afficher_db et dechiffrer_utilisateur sont les mêmes que dans la réponse précédente) ...
# (Par souci de concision, j'omets ici leur corps, mais elles sont nécessaires pour le code final)
def create_widgets(self):
# Création des champs de saisie (Nom, Login, Password)
[Link](self, text=f"Nom (César - Décalage: {DECALAGE_NOM}):", anchor="e").grid(row=0,
column=0, padx=5, pady=5, sticky="e")
self.entry_nom = [Link](self, width=40)
self.entry_nom.grid(row=0, column=1, padx=5, pady=5, sticky="w")
[Link](self, text=f"Login (César - Décalage: {DECALAGE_LOGIN}):", anchor="e").grid(row=1,
column=0, padx=5, pady=5, sticky="e")
self.entry_login = [Link](self, width=40)
self.entry_login.grid(row=1, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="Password (Hachage SHA-256):", anchor="e").grid(row=2, column=0, padx=5,
pady=5, sticky="e")
self.entry_password = [Link](self, width=40, show="*")
self.entry_password.grid(row=2, column=1, padx=5, pady=5, sticky="w")
# Bouton d'action
[Link](self, text="Chiffrer & Enregistrer", command=self.enregistrer_utilisateur, bg="#2196F3",
fg="white").grid(row=3, column=0, columnspan=2, pady=10)
# Affichage des données de la base de données
[Link](self, text="Contenu de la Base de Données (Chiffré/Haché):", font=("Arial", 10,
"bold")).grid(row=4, column=0, columnspan=2, pady=10)
self.text_output = [Link](self, height=10, width=80, state=[Link], bg="#F0F0F0")
self.text_output.grid(row=5, column=0, columnspan=2, padx=10, pady=5)
# --- SECTION: DÉCHIFFREMENT ---
row_index = 6
[Link](self, text="DÉCHIFFREMENT (Basé sur l'ID de la DB)", font=("Arial", 10,
"bold")).grid(row=row_index, column=0, columnspan=2, pady=10)
row_index += 1
[Link](self, text="ID de l'utilisateur à déchiffrer :", anchor="e").grid(row=row_index, column=0,
padx=5, pady=5, sticky="e")
self.entry_id_dechiffrement = [Link](self, width=40)
self.entry_id_dechiffrement.grid(row=row_index, column=1, padx=5, pady=5, sticky="w")
row_index += 1
[Link](self, text="Déchiffrer et Afficher les Infos", command=self.dechiffrer_utilisateur,
bg="#008CBA", fg="white").grid(row=row_index, column=0, columnspan=2, pady=10)
row_index += 1
self.text_dechiffre_output = [Link](self, height=4, width=80, state=[Link], bg="#E0F7FA")
self.text_dechiffre_output.grid(row=row_index, column=0, columnspan=2, padx=10, pady=5)
def enregistrer_utilisateur(self):
nom = self.entry_nom.get()
login = self.entry_login.get()
password = self.entry_password.get()
if not all([nom, login, password]):
[Link]("Erreur", "Tous les champs doivent être remplis.")
return
try:
# Chiffrement César pour le nom
nom_c = chiffrer_cesar(nom, DECALAGE_NOM)
# Chiffrement César pour le login
login_c = chiffrer_cesar(login, DECALAGE_LOGIN)
password_h = hacher_password(password)
# Insertion
cursor = [Link]()
[Link]('''
INSERT INTO utilisateur (nom_chiffre, login_chiffre, password_hash)
VALUES (?, ?, ?)
''', (nom_c, login_c, password_h))
[Link]()
[Link]("Succès", f"Utilisateur '{nom}' inséré.\nNom chiffré (César): {nom_c}")
self.afficher_db()
# Nettoyage
self.entry_nom.delete(0, [Link])
self.entry_login.delete(0, [Link])
self.entry_password.delete(0, [Link])
except [Link]:
[Link]("Erreur", "Ce login (chiffré) existe déjà. Choisissez un autre login.")
except Exception as e:
[Link]("Erreur", f"Une erreur est survenue lors de l'enregistrement : {e}")
print(e)
def afficher_db(self):
"""Affiche les données brutes de la base de données dans la zone de texte."""
self.text_output.config(state=[Link])
self.text_output.delete(1.0, [Link])
cursor = [Link]()
[Link]("SELECT iduser, nom_chiffre, login_chiffre, password_hash FROM utilisateur")
output_text = "ID | Nom (César) | Login (César) | Password (SHA-256 - Début)\n"
output_text += "-" * 75 + "\n"
for row in [Link]():
password_hash_display = row[3][:15] + "..."
output_text += f"{row[0]:<3}| {row[1]:<14}| {row[2]:<13}| {password_hash_display:<20}\n"
self.text_output.insert([Link], output_text)
self.text_output.config(state=[Link])
def dechiffrer_utilisateur(self):
"""Récupère un enregistrement par ID, le déchiffre et l'affiche."""
self.text_dechiffre_output.config(state=[Link])
self.text_dechiffre_output.delete(1.0, [Link])
id_str = self.entry_id_dechiffrement.get()
if not id_str:
[Link]("Erreur", "Veuillez entrer l'ID de l'utilisateur à déchiffrer.")
return
try:
user_id = int(id_str)
except ValueError:
[Link]("Erreur", "L'ID doit être un nombre entier.")
return
cursor = [Link]()
[Link]("SELECT nom_chiffre, login_chiffre, password_hash FROM utilisateur WHERE
iduser=?", (user_id,))
row = [Link]()
if row is None:
[Link]("Erreur", f"Aucun utilisateur trouvé avec l'ID {user_id}.")
self.text_dechiffre_output.config(state=[Link])
return
nom_c, login_c, password_h = row
# Déchiffrement César du Nom (avec DECALAGE_NOM)
nom_clair = dechiffrer_cesar(nom_c, DECALAGE_NOM)
# Déchiffrement César du Login (avec DECALAGE_LOGIN)
login_clair = dechiffrer_cesar(login_c, DECALAGE_LOGIN)
output_text = f"--- Informations Déchiffrées (ID: {user_id}) ---\n"
output_text += f"Nom (Clair - César) : {nom_clair}\n"
output_text += f"Login (Clair - César) : {login_clair}\n"
output_text += f"Password (Haché SHA-256) : {password_h}\n"
self.text_dechiffre_output.insert([Link], output_text)
self.text_dechiffre_output.config(state=[Link])
# --- 5. FENÊTRE D'ACCUEIL (Login/Inscription) ---
class LoginWindow([Link]):
def __init__(self):
super().__init__()
[Link]("Authentification")
[Link] = configurer_db()
self.create_widgets()
def create_widgets(self):
[Link](self, text="Connexion ou Inscription", font=("Arial", 14, "bold")).grid(row=0, column=0,
columnspan=2, pady=10)
[Link](self, text="Login:").grid(row=1, column=0, padx=5, pady=5, sticky="e")
self.entry_login = [Link](self, width=30)
self.entry_login.grid(row=1, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="Password:").grid(row=2, column=0, padx=5, pady=5, sticky="e")
self.entry_password = [Link](self, width=30, show="*")
self.entry_password.grid(row=2, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="CONNEXION", command=[Link], bg="#2ecc71", fg="white").grid(row=3,
column=0, pady=10, padx=5)
[Link](self, text="INSCRIPTION", command=self.show_inscription, bg="#3498db",
fg="white").grid(row=3, column=1, pady=10, padx=5)
def login(self):
login_clair = self.entry_login.get()
password_clair = self.entry_password.get()
if not login_clair or not password_clair:
[Link]("Erreur", "Veuillez entrer le login et le mot de passe.")
return
# 1. Hacher le mot de passe entré
password_hache_entre = hacher_password(password_clair)
# 2. Chercher dans la base de données
cursor = [Link]()
[Link]("SELECT login_chiffre, password_hash FROM utilisateur")
found_match = False
for row in [Link]():
login_chiffre_db = row[0]
password_hash_db = row[1]
# Pour vérifier le login, on déchiffre le login de la DB et on le compare au login en clair entré.
login_dechiffre_db = dechiffrer_cesar(login_chiffre_db, DECALAGE_LOGIN)
if login_dechiffre_db.upper() == login_clair.upper():
# Login trouvé. Vérifier le mot de passe
if password_hache_entre == password_hash_db:
found_match = True
break
if found_match:
[Link]("Succès", f"Connexion réussie pour l'utilisateur : {login_clair}")
# Lance l'application principale
AppChiffrementCesar(self, [Link], login_clair)
else:
[Link]("Erreur", "Login ou mot de passe incorrect.")
def show_inscription(self):
# Ouvre une fenêtre d'inscription
InscriptionWindow(self, [Link])
# --- 6. FENÊTRE D'INSCRIPTION ---
class InscriptionWindow([Link]):
def __init__(self, master, conn):
super().__init__(master)
[Link] = conn
[Link]("Inscription")
self.create_widgets()
def create_widgets(self):
[Link](self, text="Créer un Nouveau Compte", font=("Arial", 14, "bold")).grid(row=0, column=0,
columnspan=2, pady=10)
[Link](self, text="Nom:").grid(row=1, column=0, padx=5, pady=5, sticky="e")
self.entry_nom = [Link](self, width=30)
self.entry_nom.grid(row=1, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="Login:").grid(row=2, column=0, padx=5, pady=5, sticky="e")
self.entry_login = [Link](self, width=30)
self.entry_login.grid(row=2, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="Password:").grid(row=3, column=0, padx=5, pady=5, sticky="e")
self.entry_password = [Link](self, width=30, show="*")
self.entry_password.grid(row=3, column=1, padx=5, pady=5, sticky="w")
[Link](self, text="VALIDER L'INSCRIPTION", command=[Link], bg="#3498db",
fg="white").grid(row=4, column=0, columnspan=2, pady=10)
def inscrire(self):
nom_clair = self.entry_nom.get()
login_clair = self.entry_login.get()
password_clair = self.entry_password.get()
if not all([nom_clair, login_clair, password_clair]):
[Link]("Erreur", "Tous les champs doivent être remplis.")
return
try:
# 1. Chiffrement des données pour la DB
nom_c = chiffrer_cesar(nom_clair, DECALAGE_NOM)
login_c = chiffrer_cesar(login_clair, DECALAGE_LOGIN)
password_h = hacher_password(password_clair)
# 2. Insertion
cursor = [Link]()
[Link]('''
INSERT INTO utilisateur (nom_chiffre, login_chiffre, password_hash)
VALUES (?, ?, ?)
''', (nom_c, login_c, password_h))
[Link]()
[Link]("Succès", "Compte créé avec succès ! Vous pouvez vous connecter.")
[Link]() # Ferme la fenêtre d'inscription
except [Link]:
[Link]("Erreur", "Ce login (chiffré) existe déjà. Choisissez un autre login.")
except Exception as e:
[Link]("Erreur", f"Une erreur est survenue lors de l'enregistrement : {e}")
print(e)
# --- 7. EXECUTION PRINCIPALE ---
if __name__ == "__main__":
app = LoginWindow()
[Link]()