Projet Privalis
Système d'Enchères Sécurisé & Architecture Réflexive
Vision & Problématique
Privalis est une plateforme distribuée d'enchères au second prix (Vickrey). Dans ce modèle "à plis fermés", l'anonymat des offres et l'intégrité du protocole sont critiques : les montants ne doivent être révélés qu'après la clôture, et aucun acteur (pas même le serveur) ne doit pouvoir altérer une offre sans être détecté.
Logique & Justification
Le choix de l'enchère de Vickrey impose une architecture où le Serveur est un pur relais de stockage (aveugle aux prix) tandis que l'Autorité est le seul tiers de confiance capable de lever le secret. Cette séparation des pouvoirs est la clé de la non-répudiation et de l'équité du système.
Analyse Fonctionnelle (DCU)
Diagramme de Cas d'Utilisation (DCU) modélisant les interactions métiers et la frontière du système.
Le fonctionnement repose sur une orchestration précise entre les acteurs :
- Enchérisseur : Il ne se contente pas d'envoyer un prix. Il doit générer une preuve cryptographique (chiffrement RSA pour l'Autorité) et signer le résultat pour garantir que l'offre émane bien de lui.
- Vendeur (S) : Il prépare la session. Il reçoit les plis sans pouvoir les ouvrir, garantissant la règle du "pli fermé".
- Autorité (A) : Elle n'intervient qu'à la fin pour le déchiffrement massif, le tri des deux meilleurs prix et la déclaration du vainqueur, empêchant toute fraude de la part du vendeur.
Développement Chronologique
Sprint 1 : Socle & Persistance
01 oct. — 16 oct.- Modélisation du domaine (Enchères, Utilisateurs, Objets Data).
- Développement de l'ORM maison (MapperObjet) et Repository.
- Initialisation de la base de données Oracle SQL.
Sprint 2 : Architecture Réseau
17 oct. — 13 nov.- Implémentation du Routeur Dynamique (dispatching JSON-RPC).
- Gestion du multithreading serveur et BufferSortie thread-safe.
- Mise en place des premiers contrôleurs métiers (Enchères, Utilisateurs).
Sprint 3 : Sécurité Fondamentale
14 nov. — 30 nov.- Configuration des Sockets SSL/TLS (Client & Serveur).
- Gestionnaire de clés RSA-4096 avec stockage local sécurisé.
- Définition du contrat de signature et de chiffrement hybride.
Sprint 4 : Protocole Vickrey
01 déc. — 17 déc.- Orchestration du protocole de soumission (Client side automate).
- Implémentation du Broadcast Vérifié (tri lexicographique).
- Calcul sécurisé du second prix par l'Autorité côté serveur.
Sprint 5 : Intégration & Audit
18 déc. — 13 janv.- Audit de sécurité : Simulation d'attaques sur le broadcast.
- Gestion des cas d'erreurs critiques et signalement de fraude.
- Finalisation des interfaces graphiques et tests d'intégration massifs.
Phase 2 : Restructuration & Industrialisation
La seconde phase du projet se concentre sur la robustesse du système et la facilité de déploiement.
1. Conception & Tests à Grande Échelle
L'application a été restructurée selon les meilleures pratiques de conception logicielle. Pour garantir la fiabilité du système sous charge, nous avons mis en œuvre une suite de tests unitaires massifs (JUnit) et des tests d'intégration simulant des centaines d'enchérisseurs simultanés.
2. Déploiement Conteneurisé (Docker)
Pour simplifier l'installation et assurer la reproductibilité de l'environnement,
l'intégralité du système (Serveur, Client, Base de données Oracle) est désormais
conteneurisée via Docker. Un simple docker-compose up permet
de déployer l'infrastructure complète.
Architecture du Serveur
Le serveur est le pivot central du projet. J'en ai conçu l'intégralité du socle technique selon un modèle de haute performance et de sécurité.
1. Dispatching Dynamique & Routage
Le serveur reçoit des requêtes JSON-RPC. Pour éviter un code spaghetti de tests conditionnels (if/else), j'ai mis en place un Routeur Dynamique. Ce dernier identifie le contrôleur et l'action à exécuter à partir du JSON pour invoquer la logique associée via une référence de méthode.
Automatisation Quartz : Le serveur s'appuie depuis la Phase 1 sur le scheduler Quartz pour automatiser l'ouverture et la fermeture des sessions d'enchères à la milliseconde près, garantissant une intégrité temporelle absolue sans intervention humaine.
// Dans Routeur.java - Recherche dynamique de l'action
private static Function<JSONObject, JSONObject> getMethod(JSONObject json) {
String action = json.get("action").toString();
String nomController = json.get("controller").toString();
for (AbstractController controller : controllers) {
if (controller.getNom().equals(nomController)) {
if (controller.contientAction(action)) {
IMethodeControlleur methode = controller.getAction(action);
return methode::action; // Dispatching via référence de méthode
}
}
}
return null;
}
Logique : Cette approche découple totalement la couche réseau des contrôleurs métiers. Ajouter une fonctionnalité consiste simplement à enregistrer une méthode dans un contrôleur ; le serveur la reconnaîtra automatiquement sans modification du code source de routage.
2. Gestion Multithread & BufferSortie
Dans un environnement socket, l'envoi de messages est une opération bloquante. J'ai créé la
classe BufferSortie pour implémenter un modèle
Producteur/Consommateur thread-safe s'appuyant sur des
CompletableFuture.
// Dans BufferSortie.java - Synchronisation via Future
public class BufferSortie {
private static final Map<String, CompletableFuture<JSONObject>> buffers = new ConcurrentHashMap<>();
/** Appelé pour envoyer la réponse au bon client */
public static void setBuffer(String id, JSONObject buffer) {
CompletableFuture<JSONObject> future = buffers.get(id);
if (future != null) {
future.complete(buffer); // Produit et réveille le client
}
}
/** Appelé pour attendre le résultat du contrôleur */
public static JSONObject readBuffer(String id) {
CompletableFuture<JSONObject> future = buffers.get(id);
return future.get(); // Bloquant jusqu'au setBuffer
}
}
Logique : Cette architecture garantit qu'un client avec une connexion lente n'impacte jamais les performances globales du serveur. Le thread métier "dépose" le message et repart immédiatement s'occuper des autres requêtes.
3. Le Moteur de Persistance (ORM)
Sans utiliser de bibliothèque externe, j'ai développé un ORM capable de mapper des graphes d'objets Java complexes vers du JSON, gérant automatiquement les clés primaires et les relations entre tables.
// Dans MapperObjet.java - Détection de cycles
public static TreeMap<String, Object> mapper(AbstractDataObject modele, ArrayList<Object> visites) {
visites.add(modele);
// ...
for (Field champ : champs) {
Object object = methode.invoke(modele);
if (!visites.contains(object)) {
// Sérialisation récursive si l'objet n'a pas été visité
map.put(nomAttribut, MapperObjet.mapper((AbstractDataObject) object, visites));
}
}
return map;
}
Défi technique : Gérer les cycles (ex: Vente -> Enchère -> Vente). Mon ORM maintient un registre d'objets déjà visités lors de la sérialisation récursive, injectant des références là où une boucle infinie se formerait normalement.
Conception du Client (Architecture Automate)
Abstraction du Protocole
Côté client, la gestion du protocole cryptographique complexe (Vickrey) est isolée dans une
interface ProtocoleEnchere. Cette abstraction permet de définir des étapes de
communication séquentielles et interchangeables pour la gestion des enchères.
// Dans ProtocoleEnchere.java - Orchestration des étapes
@Override
public void run() {
// Phase 1 : Soumission de l'enchère
EnvoiDeEnchere envoiDeEnchere = new EnvoiDeEnchere(prix);
byte[] chiffreOriginal = envoiDeEnchere.executer(getClient());
// Phase 2 : Réception du broadcast et vérification
VerificationBroadcast verificationBroadcast = new VerificationBroadcast(chiffreOriginal, idEnchere);
Boolean signatureCorrecte = verificationBroadcast.executer(getClient());
if (!signatureCorrecte) {
// Signalement d'une fraude détectée
new ErreurSignatureBroadcast(idEnchere).executer(getClient());
}
}
Le modèle synchrone du client : Le client suit un automate fini. Il envoie une donnée et attend *précisément* le type de réponse attendu par le protocole (ex: Signature z du serveur). Cette certitude facilite la vérification des preuves cryptographiques à chaque étape.
Comparaison : Sync (Client) vs Event (Serveur)
Le projet force une cohabitation entre deux paradigmes :
- Client (Sync-like) : Précis, facile à vérifier cryptographiquement, assure que chaque phase est validée avant la suivante. Inconvénient : Moins souple.
- Serveur (Event-driven) : Réagit aux messages sans connaître l'historique complet. Avantage : Supporte des milliers de connexions simultanées sans blocage.
Le Protocole Vickrey pas à pas (DSS)
Visualisation du nouveau protocole de sécurité homomorphe implémenté.
Phase 1 : Enchère Homomorphe
L'enchérisseur encode son prix bi et le chiffre via le protocole de
Damgård-Jurik : ci = Enc(B^bi ; ri) mod N^s+1. Le serveur (S)
recueille ces chiffrés sans pouvoir les lire et calcule le produit homomorphe
c = Π ci. Cette propriété permet d'agréger les offres tout en préservant le
secret total.
Phase 2 : Ouverture & Autorité
L'Autorité (A) reçoit le produit c, vérifie la signature globale du serveur, et
utilise sa clé secrète pour déchiffrer. Grâce à la structure mathématique
(1+N)^m du protocole Damgård-Jurik, l'Autorité peut extraire le second prix
p2 sans jamais avoir eu accès aux offres individuelles originales.
Annexes Techniques
Le diagramme de classes suivant détaille l'organisation structurelle des objets métiers et de la couche de données.
Contribution & Leadership
Rôle : Product Owner & Lead Architecte.
Impact : Architecture du socle réseau (Sockets SSL/TLS), moteur JSON-RPC et coordination technique de l'équipe.
En tant que Lead Architecte, j'ai conçu le socle système
du projet, notamment via la création de la classe Protocole côté client et le
développement de la logique de diffusion thread-safe côté serveur. Au-delà de ces fondations
réseau,
j'ai participé activement à tous les niveaux du cycle de vie : du développement de
l'interface utilisateur pour simplifier l'UX du protocole, jusqu'à la
collaboration
sur les couches de chiffrement RSA. Ma priorité a été d'assurer une intégration
fluide entre la robustesse technique du backend et l'expérience utilisateur finale.
Compétences mobilisées
Hard Skills
- Java & Réseaux : Sockets SSL/TLS, Multithreading, Réflexion.
- Architectures : Design par automate, patterns Repository et Controller.
- Cybersécurité : Chiffrement asymétrique RSA-4096 et Signatures numériques.
Soft Skills
- Product Ownership : Vision long-terme et arbitrage de complexité.
- Analyse de Risques : Identification des failles potentielles du protocole.
- Leadership : Pilotage d'une équipe technique vers un objectif de sécurité critique.
Bilan & Perspectives
Privalis a été l'un des défis les plus stimulants de mon cursus, exigeant une rigueur absolue tant sur la théorie cryptographique que sur la pratique de l'architecture distribuée. Le succès de cette plateforme réside dans l'équilibre trouvé entre haute sécurité et fluidité d'utilisation.
Ce projet m'a non seulement permis de consolider mes compétences techniques en Java avancé et en cybersécurité, mais il a aussi renforcé ma capacité à piloter des projets complexes où chaque ligne de code impacte directement l'intégrité globale du système. C'est cette vision "Full-Stack Sécurité" que je souhaite continuer à explorer.