- Created `/frontend/app/api/votes/check/route.ts` to handle GET requests for checking if a user has voted in a specific election. - Added error handling for unauthorized access and missing election ID. - Forwarded requests to the backend API and returned appropriate responses. - Updated `/frontend/app/api/votes/history/route.ts` to fetch user's voting history with error handling. - Ensured both endpoints utilize the authorization token for secure access.
845 lines
23 KiB
Typst
845 lines
23 KiB
Typst
#set page(margin: (top: 2cm, bottom: 2cm, left: 2.5cm, right: 2.5cm))
|
||
#set text(font: "New Computer Modern", size: 11pt)
|
||
#set heading(numbering: "1.1.1")
|
||
#show heading: it => {
|
||
it
|
||
v(0.5em)
|
||
}
|
||
#show link: underline
|
||
|
||
#align(center)[
|
||
= Système de Vote Électronique Sécurisé
|
||
== Avec Cryptographie Post-Quantique Hybride
|
||
|
||
Rapport Technique et Scientifique
|
||
|
||
*EPITA - Cryptographie Industrielle Avancée* \
|
||
*Novembre 2025* \
|
||
*CIA Team*
|
||
]
|
||
|
||
#pagebreak()
|
||
|
||
= Résumé Exécutif
|
||
|
||
Ce rapport documente la conception et l'implémentation d'un *prototype fonctionnel* d'un système de vote électronique sécurisé. Le système applique les principes fondamentaux de la cryptographie pour adresser les défis spécifiques du vote en ligne :
|
||
- *Fraude* : Prévention de modification/double-vote via blockchain
|
||
- *Intimidation* : Confidentialité des votes via chiffrement homomorphe
|
||
- *Anonymat* : Séparation entre identité et bulletin de vote
|
||
|
||
Les principales contributions :
|
||
- Cryptographie *post-quantique hybride* (NIST FIPS 203/204/205)
|
||
- Chiffrement ElGamal avec *addition homomorphe* pour dépouillement sécurisé
|
||
- Signatures *hybrides RSA-PSS + Dilithium* (quantum-resistant)
|
||
- Architecture *blockchain* pour immuabilité
|
||
- Déploiement *Docker autonome* et reproductible
|
||
|
||
#pagebreak()
|
||
|
||
= 1. Introduction
|
||
|
||
== 1.1 Contexte et Motivation
|
||
|
||
Les systèmes de vote électronique doivent résoudre plusieurs défis de sécurité interdépendants :
|
||
|
||
1. *Fraude Électorale* : Modification des votes, double-vote, forgerie
|
||
2. *Intimidation/Coercion* : Personne ne doit pouvoir forcer l'électeur à voter d'une certaine façon
|
||
3. *Anonymat* : Séparation entre identité du votant et son choix
|
||
4. *Intégrité* : Les votes ne doivent pas pouvoir être modifiés après soumission
|
||
5. *Immuabilité* : Audit trail complet et vérifiable
|
||
|
||
|
||
= 2 Architecture et Conception du Système
|
||
|
||
== 2.1 Vue Globale
|
||
|
||
L'architecture suit un modèle Client/Serveur + Blockchain :
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ Frontend Web (Next.js) │
|
||
│ - Interface d'authentification │
|
||
│ - Sélection du candidat │
|
||
│ - Chiffrement du vote │
|
||
└──────────────┬────────────────────────────┘
|
||
│ HTTPS/REST JSON
|
||
┌──────────────▼────────────────────────────┐
|
||
│ Backend API (FastAPI) │
|
||
│ - Authentication JWT │
|
||
│ - Validation et chiffrement hybride │
|
||
│ - Signatures RSA + Dilithium │
|
||
│ - Gestion blockchain │
|
||
└──┬─────────────────────────────┬──────────┘
|
||
│ │
|
||
┌──▼──────────┐ ┌────────▼──────────┐
|
||
│ MariaDB │ │ Blockchain (PoA) │
|
||
│ Voters │ │ - Vote blocks │
|
||
│ Elections │ │ - Validators │
|
||
│ Votes │ │ - PoA consensus │
|
||
└─────────────┘ └───────────────────┘
|
||
```
|
||
|
||
== 2.2 Composants Principaux
|
||
|
||
=== Frontend (Next.js 15 + React 18)
|
||
|
||
*Responsabilités* :
|
||
- Interface utilisateur responsive
|
||
- Authentification (login/register)
|
||
- Sélection de candidat
|
||
- Visualisation des résultats
|
||
|
||
*Technologies* :
|
||
- Next.js 15 pour server-side rendering
|
||
- React 18 avec hooks
|
||
- TypeScript pour type safety
|
||
- Tailwind CSS pour le design
|
||
|
||
=== Backend (FastAPI + Python 3.12)
|
||
|
||
*Responsabilités* :
|
||
- Authentification JWT
|
||
- Gestion des élections
|
||
- Chiffrement hybride (ElGamal + Kyber)
|
||
- Signatures hybrides (RSA + Dilithium FIPS 204)
|
||
- Stockage blockchain des votes
|
||
|
||
*Endpoints clés* :
|
||
- `POST /api/auth/register` - Inscription avec génération clés PQC
|
||
- `POST /api/auth/login` - Authentification
|
||
- `GET /api/elections/active` - Élection active
|
||
- `POST /api/votes/submit` - Soumission vote signé+chiffré
|
||
- `GET /api/elections/{id}/results` - Résultats
|
||
|
||
=== Base de Données (MariaDB)
|
||
|
||
*Schéma* :
|
||
- Voters : Électeurs avec hachage bcrypt
|
||
- Elections : Configurations avec paramètres ElGamal
|
||
- Candidates : Options de vote
|
||
- Votes : Bulletins chiffrés (stockage séparé pour confidentialité)
|
||
|
||
=== Blockchain (Python + PoA Validators)
|
||
|
||
*Composants* :
|
||
- Blockchain locale : stockage immuable des votes
|
||
- Signature Dilithium : authenticité de chaque bloc
|
||
- Chaîne de hachage SHA-256 : intégrité
|
||
- PoA Validators : consensus distribué optionnel
|
||
|
||
#pagebreak()
|
||
|
||
= 3 Cryptographie Post-Quantique Hybride
|
||
|
||
== 3.1 Motivation et Stratégie
|
||
|
||
*Menace Quantique* : Les ordinateurs quantiques théoriques cassent RSA/ElGamal classiques en temps polynomial (algorithme de Shor).
|
||
|
||
*Defense-in-Depth* : Combinaison classique + post-quantique :
|
||
- Si RSA cassé → Dilithium (FIPS 204) reste sûr
|
||
- Si Dilithium cassé → RSA classique reste sûr
|
||
- Aucun point de défaillance unique cryptographique
|
||
|
||
== 3.2 Composants Certifiés NIST
|
||
|
||
=== Signatures Hybrides : RSA-PSS + ML-DSA-65 (Dilithium)
|
||
|
||
*RSA-PSS (Classique)* :
|
||
- Taille clé : 2 048 bits
|
||
- Sécurité : ~128 bits classique
|
||
- Algorithme établi depuis 1977
|
||
|
||
*ML-DSA-65 (FIPS 204)* :
|
||
- Basé sur problème LWE (Learning With Errors)
|
||
- Taille signature : 2 420 bytes
|
||
- Sécurité : 192-bit post-quantique
|
||
- Finalisé par NIST : 2024
|
||
|
||
*Processus de signature hybride* :
|
||
```
|
||
message = vote_data
|
||
sig_rsa = RSA-PSS.sign(message, rsa_private_key)
|
||
sig_dilithium = ML-DSA-65.sign(message, dilithium_private_key)
|
||
|
||
# Vérification : LES DEUX doivent être valides
|
||
assert RSA-PSS.verify(message, sig_rsa, rsa_public_key)
|
||
assert ML-DSA-65.verify(message, sig_dilithium, dilithium_public_key)
|
||
```
|
||
|
||
=== Chiffrement Hybride : ElGamal + ML-KEM-768 (Kyber)
|
||
|
||
*ElGamal (Classique)* :
|
||
- Groupe : $Z_p^*$ avec premier $p$
|
||
- Propriété : Addition homomorphe
|
||
- Sécurité : IND-CPA sémantiquement sûr
|
||
|
||
*ML-KEM-768 (FIPS 203)* :
|
||
- Basé sur problème LWE
|
||
- Taille ciphertext : 1 088 bytes
|
||
- Sécurité : 192-bit post-quantique
|
||
- Finalisé par NIST : 2024
|
||
|
||
*Processus d'encapsulation hybride* :
|
||
```
|
||
# Kyber : Key Encapsulation Mechanism
|
||
kyber_ct, kyber_ss = ML-KEM-768.encap(kyber_public_key)
|
||
|
||
# ElGamal : Classic encryption
|
||
eg_ct = ElGamal.encrypt(message, elgamal_public_key)
|
||
|
||
# Fusion des secrets
|
||
final_key = SHA-256(kyber_ss || eg_ss)
|
||
|
||
# Chiffrement symétrique du bulletin
|
||
encrypted_ballot = AES-256-GCM.encrypt(final_key, ballot)
|
||
```
|
||
|
||
=== Hachage : SHA-256
|
||
|
||
- Sortie : 256 bits
|
||
- Résistant quantique pour preimage
|
||
- Quantum computer : ~$2^{128}$ opérations pour collision (Grover)
|
||
- Toujours infaisable pratiquement
|
||
|
||
== 3.3 Propriétés Homomorphes d'ElGamal
|
||
|
||
*Définition* : Chiffrement addif homomorphe = opérations sur ciphertexts → opérations sur plaintexts.
|
||
|
||
Pour ElGamal avec groupe multiplicatif $G$ :
|
||
|
||
$
|
||
E(m_1) times E(m_2) = E(m_1 + m_2)
|
||
$
|
||
|
||
*Preuve* :
|
||
```
|
||
E(m₁) = (c₁, c₂) = (g^r₁, m₁ · h^r₁)
|
||
E(m₂) = (c₁', c₂') = (g^r₂, m₂ · h^r₂)
|
||
|
||
E(m₁) × E(m₂) = (g^r₁ · g^r₂, m₁·h^r₁ · m₂·h^r₂)
|
||
= (g^(r₁+r₂), (m₁+m₂)·h^(r₁+r₂))
|
||
= E(m₁ + m₂) ✓
|
||
```
|
||
|
||
*Application au vote* :
|
||
```
|
||
Vote binaire : chaque candidat reçoit 0 ou 1
|
||
|
||
E(total_candidat_A) = E(1) × E(0) × ... × E(1)
|
||
= E(1 + 0 + ... + 1)
|
||
= E(nombre de votes pour A)
|
||
|
||
Dépouillement :
|
||
1. Récupérer tous E(vote_i) de la blockchain
|
||
2. Calculer E(total) = ∏ E(vote_i)
|
||
3. Déchiffrer UNE SEULE FOIS : total = Dec(E(total))
|
||
4. Publier résultats anonymes
|
||
```
|
||
|
||
#pagebreak()
|
||
|
||
= 4 Flux Complet du Processus de Vote
|
||
|
||
== 4.1 Phase 1 : Inscription
|
||
|
||
```
|
||
Électeur : Entre email, nom, CNI, mot de passe
|
||
↓
|
||
Backend :
|
||
1. Vérifier email unique
|
||
2. Générer clés hybrides :
|
||
- RSA 2048 (signature)
|
||
- ML-DSA-65/Dilithium (signature)
|
||
- ElGamal (chiffrement)
|
||
- ML-KEM-768/Kyber (KEM)
|
||
3. Hacher mot de passe avec bcrypt
|
||
4. Enregistrer dans BD
|
||
↓
|
||
Frontend : Afficher confir mation et rediriger vers login
|
||
```
|
||
|
||
== 4.2 Phase 2 : Authentification
|
||
|
||
```
|
||
Électeur : Entrer email + mot de passe
|
||
↓
|
||
Backend :
|
||
1. Vérifier email existe
|
||
2. Vérifier password avec bcrypt
|
||
3. Générer JWT token (30 min expiration)
|
||
4. Retourner token
|
||
↓
|
||
Frontend : Stocker token, rediriger vers élections
|
||
```
|
||
|
||
== 4.3 Phase 3 : Affichage de l'Élection
|
||
|
||
```
|
||
Frontend : GET /api/elections/active
|
||
↓
|
||
Backend :
|
||
1. Vérifier JWT valide et non expiré
|
||
2. Vérifier électeur authentifié
|
||
3. Récupérer élection active depuis BD
|
||
4. Récupérer candidats
|
||
↓
|
||
Frontend : Afficher liste candidats
|
||
```
|
||
|
||
== 4.4 Phase 4 : Soumission du Vote
|
||
|
||
```
|
||
Électeur : Sélectionner candidat A
|
||
↓
|
||
Frontend :
|
||
1. Créer ballot = {election_id, candidat_id, timestamp}
|
||
2. Hacher : ballot_hash = SHA-256(ballot)
|
||
3. Signer avec RSA + Dilithium
|
||
4. Chiffrer avec ElGamal + Kyber
|
||
↓
|
||
Backend (POST /api/votes/submit) :
|
||
1. Vérifier JWT
|
||
2. Vérifier pas déjà voté (check voters.has_voted)
|
||
3. Vérifier signature RSA valide
|
||
4. Vérifier signature Dilithium valide
|
||
5. Vérifier élection active
|
||
6. Ajouter bloc blockchain :
|
||
Block {
|
||
index: len(chain) + 1
|
||
prev_hash: SHA-256(previous_block)
|
||
encrypted_vote: vote_chiffré
|
||
signature: DILITHIUM.sign(block_hash)
|
||
}
|
||
7. Marquer voters.has_voted = True
|
||
8. Retourner confirmation
|
||
↓
|
||
Frontend : Afficher confirmation avec ballot_hash
|
||
```
|
||
|
||
== 4.5 Phase 5 : Dépouillement Sécurisé
|
||
|
||
```
|
||
Admin : Demander résultats après clôture
|
||
↓
|
||
Backend :
|
||
1. Récupérer tous votes chiffrés de blockchain
|
||
2. Addition homomorphe :
|
||
E(total_A) = ∏ E(vote_candidat_A_i)
|
||
3. Déchiffrer :
|
||
total_A = Dec_sk(E(total_A))
|
||
4. Publier résultats anonymes
|
||
↓
|
||
Frontend : Afficher résultats (graphiques)
|
||
```
|
||
|
||
== 4.6 Phase 6 : Vérification et Audit
|
||
|
||
```
|
||
Vérificateur : Audit complet
|
||
1. Récupérer blockchain complète
|
||
2. Vérifier intégrité chaîne :
|
||
for each block in chain:
|
||
assert block.block_hash == SHA-256(block_content)
|
||
assert DILITHIUM.verify(block.signature)
|
||
assert block.prev_hash == previous.block_hash
|
||
3. Compter votes : len(chain) - 1 (exclude genesis)
|
||
4. Vérifier chaque électeur n'a voté qu'une fois
|
||
5. Publier rapport d'audit
|
||
↓
|
||
Result : Élection vérifiée et trustworthy
|
||
```
|
||
|
||
#pagebreak()
|
||
|
||
= 5 Propriétés de Sécurité Formelles
|
||
|
||
== 5.1 Confidentialité du Vote
|
||
|
||
*Définition* : Adversaire ne peut déterminer pour qui a voté un électeur.
|
||
|
||
*Garantie* : ElGamal sémantiquement sûr (IND-CPA)
|
||
- Vote chiffré : $E(v) = (c_1, c_2)$
|
||
- Même plaintext produit différents ciphertexts (probabiliste)
|
||
- Sans clé privée $x$ : impossible de déchiffrer
|
||
|
||
*Protection* : Kyber (post-quantique) renforce cette propriété contre ordinateurs quantiques.
|
||
|
||
== 5.2 Intégrité des Votes
|
||
|
||
*Définition* : Vote ne peut être modifié après soumission.
|
||
|
||
*Garantie* : Blockchain avec chaîne de hachage SHA-256
|
||
|
||
```
|
||
Block_0 → Block_1 → Block_2 → ... → Block_n
|
||
|
||
Si attaquant modifie Block_k:
|
||
1. block_hash[Block_k] change
|
||
2. prev_hash[Block_{k+1}] != block_hash[Block_k]
|
||
3. Tous blocs suivants invalides
|
||
4. Détection certaine lors vérification
|
||
```
|
||
|
||
*Protection* : Signature Dilithium sur chaque bloc.
|
||
|
||
== 5.3 Non-Répudiation
|
||
|
||
*Définition* : Électeur ne peut nier avoir voté.
|
||
|
||
*Garantie* : Signatures hybrides RSA + Dilithium
|
||
|
||
```
|
||
Vote signé avec DEUX signatures :
|
||
sig_rsa = RSA-PSS.sign(ballot, rsa_sk)
|
||
sig_dilithium = ML-DSA-65.sign(ballot, dilithium_sk)
|
||
|
||
Électeur prétend ne pas avoir signé:
|
||
→ Produit clés différentes
|
||
→ Signatures RSA ou Dilithium échouent
|
||
→ Contradiction prouvable
|
||
```
|
||
|
||
== 5.4 Authentification du Votant
|
||
|
||
*Définition* : Vote vient d'électeur authentifié.
|
||
|
||
*Garantie* : JWT + bcrypt
|
||
|
||
```
|
||
1. Électeur login → reçoit JWT signé(SECRET_KEY, {voter_id, exp})
|
||
2. Vote includs Authorization: Bearer <JWT>
|
||
3. Backend vérifie :
|
||
- JWT signature valide
|
||
- JWT non expiré
|
||
- voter_id du JWT = voter du vote
|
||
```
|
||
|
||
== 5.5 Anti-Coercion (Partiel)
|
||
|
||
*Définition* : Électeur ne peut prouver son vote à un tiers.
|
||
|
||
*Approche* :
|
||
- Votes chiffrés : attaquant ne peut vérifier
|
||
- Preuves ZK non-transférables : secret pas révélé
|
||
- Backend seul connaît secrets de déchiffrement
|
||
|
||
*Limitation* : Si attaquant observe l'écran directement → nécessite isolement physique.
|
||
|
||
#pagebreak()
|
||
|
||
= 6 Analyse des Menaces et Mitigations
|
||
|
||
== 6.1 Fraude Électorale
|
||
|
||
*Menace* : Modification des votes après soumission
|
||
|
||
*Mitigation* :
|
||
- Chaîne de hachage SHA-256 : modification d'un vote invalide toute la chaîne
|
||
- Signature Dilithium : bloc non-signable sans clé privée
|
||
- Vérification publique possible
|
||
- Addition homomorphe détecterait votes modifiés
|
||
|
||
*Risque résiduel* : Faible (détection certaine)
|
||
|
||
== 6.2 Double-Vote
|
||
|
||
*Menace* : Même électeur vote deux fois
|
||
|
||
*Mitigation* :
|
||
- Constraint unique (voter_id, election_id)
|
||
- voters.has_voted flag
|
||
- Vérification backend avant enregistrement
|
||
- Blockchain enregistre une fois
|
||
|
||
*Risque résiduel* : Aucun (prévention garantie)
|
||
|
||
== 6.3 Usurpation d'Identité
|
||
|
||
*Menace* : Attaquant vote au nom d'autrui
|
||
|
||
*Mitigation* :
|
||
- Authentification JWT forte
|
||
- Vérification identité à l'inscription (CNI)
|
||
- Mot de passe bcrypt
|
||
- Tokens non-transférables
|
||
|
||
*Risque résiduel* : Faible (si acces device de l'électeur)
|
||
|
||
== 6.4 Intimidation / Coercion
|
||
|
||
*Menace* : Tiers force électeur à voter d'une certaine façon
|
||
|
||
*Mitigation (partielle)* :
|
||
- Vote chiffré : coerciteur ne peut vérifier
|
||
- Votes anonymes : liaison identité-bulletin impossible
|
||
- Preuves ZK : électeur ne peut transférer preuve du vote
|
||
|
||
*Risque résiduel* : Modéré (si observation directe de l'écran)
|
||
- Mitigations complémentaires : isolement physique du bureau, caméras (si légal)
|
||
|
||
== 6.5 Attaque Administrateur
|
||
|
||
*Menace* : Admin avec accès BD compromet tout
|
||
|
||
*Mitigation* :
|
||
- Principle of least privilege
|
||
- Audit logs séparés
|
||
- Chiffrement données sensibles
|
||
- Secrets dans env vars, pas en code
|
||
|
||
*Risque résiduel* : Élevé si BD compromise
|
||
- Mitigation : infrastructure sécurisée, backups chiffrés
|
||
|
||
== 6.6 Attaque Quantique Future
|
||
|
||
*Menace* : Ordinateur quantique décrypte RSA/ElGamal
|
||
|
||
*Mitigation* :
|
||
- Chiffrement hybride ElGamal + Kyber
|
||
- Signatures hybrides RSA + Dilithium
|
||
- Hachage SHA-256 (quantum-resistant pour preimage)
|
||
|
||
*Résultat* : Sécurité maintenue si au moins l'un des systèmes reste sûr
|
||
|
||
== 6.7 Injection SQL
|
||
|
||
*Menace* : Exploit requête SQL malveillante
|
||
|
||
*Mitigation* :
|
||
- SQLAlchemy ORM : prévient injections
|
||
- Prepared statements implicites
|
||
- Type hints + validation Pydantic
|
||
|
||
*Risque résiduel* : Minimal
|
||
|
||
#pagebreak()
|
||
|
||
= 7 Implémentation Technique
|
||
|
||
== 7.1 Stack Technologique
|
||
|
||
=== Backend
|
||
|
||
*Python 3.12*
|
||
- Type hints modernes (PEP 484, 585)
|
||
- Performance améliorée (3.12+ optimisations)
|
||
- Async/await natif
|
||
|
||
*FastAPI*
|
||
- Framework moderne ASGI
|
||
- Documentation auto (OpenAPI/Swagger)
|
||
- Validation Pydantic intégrée
|
||
- Performance compétitive (bench: 3-5x plus rapide que Django)
|
||
|
||
*SQLAlchemy 2.0*
|
||
- ORM robuste
|
||
- Type-safe queries
|
||
- Support transactions ACID
|
||
|
||
*liboqs-python*
|
||
- Bindings pour librairie C liboqs
|
||
- Algorithmes NIST certifiés
|
||
- ML-DSA-65 (Dilithium), ML-KEM-768 (Kyber)
|
||
|
||
=== Frontend
|
||
|
||
*Next.js 15*
|
||
- SSR (Server-Side Rendering) : sécurité
|
||
- Static generation quand possible
|
||
- Image optimization automatique
|
||
- API routes intégrées
|
||
|
||
*React 18*
|
||
- Hooks modernes
|
||
- Concurrent features
|
||
- Strict mode détecte problèmes
|
||
|
||
*TypeScript*
|
||
- Type safety complet
|
||
- Better IDE support
|
||
- Documentation via types
|
||
|
||
*Tailwind CSS + Shadcn*
|
||
- Utility-first CSS
|
||
- Thème cohérent
|
||
- Accessible par défaut
|
||
|
||
=== Infrastructure
|
||
|
||
*Docker Compose*
|
||
- Orchestration local/dev
|
||
- Volumes persistants
|
||
- Networks isolation
|
||
- Health checks
|
||
|
||
*MariaDB*
|
||
- ACID transactions
|
||
- Replication support
|
||
- Performant
|
||
- Compatible MySQL
|
||
|
||
== 7.2 Architecture de Fichiers
|
||
|
||
```
|
||
backend/
|
||
├── main.py # Application FastAPI
|
||
├── config.py # Configuration (env vars)
|
||
├── models.py # SQLAlchemy models
|
||
├── schemas.py # Pydantic schemas
|
||
├── auth.py # Authentification JWT
|
||
├── database.py # Connexion BD
|
||
├── services.py # Logique métier
|
||
├── blockchain.py # Blockchain local
|
||
├── blockchain_elections.py # Elections blockchain
|
||
├── blockchain_client.py # Client PoA
|
||
├── init_blockchain.py # Initialisation blockchain
|
||
├── crypto/
|
||
│ ├── pqc_hybrid.py # Crypto post-quantique hybride
|
||
│ ├── encryption.py # ElGamal + AES
|
||
│ ├── signatures.py # RSA-PSS
|
||
│ ├── hashing.py # SHA-256
|
||
│ └── zk_proofs.py # Preuves ZK
|
||
└── routes/
|
||
├── auth.py # /api/auth/*
|
||
├── elections.py # /api/elections/*
|
||
└── votes.py # /api/votes/*
|
||
```
|
||
|
||
== 7.3 Endpoints API
|
||
|
||
| Endpoint | Méthode | Description |
|
||
|----------|---------|-------------|
|
||
| `/api/auth/register` | POST | Inscription + génération clés |
|
||
| `/api/auth/login` | POST | Authentification |
|
||
| `/api/auth/profile` | GET | Profil électeur |
|
||
| `/api/elections/active` | GET | Élection courante |
|
||
| `/api/elections/{id}` | GET | Détails élection |
|
||
| `/api/elections/{id}/candidates` | GET | Candidats |
|
||
| `/api/votes/submit` | POST | Soumission vote |
|
||
| `/api/elections/{id}/results` | GET | Résultats |
|
||
| `/api/blockchain/votes` | GET | Blockchain complète |
|
||
| `/api/blockchain/verify` | POST | Vérifier intégrité |
|
||
|
||
#pagebreak()
|
||
|
||
= 8 Tests et Validation
|
||
|
||
== 8.1 Suite de Tests
|
||
|
||
=== Tests Unitaires Cryptographiques
|
||
|
||
*ElGamal* (`test_crypto.py`) :
|
||
```
|
||
✓ test_keygen : Génération clés valides
|
||
✓ test_encrypt_decrypt : Chiffrement/déchiffrement
|
||
✓ test_semantic_security : Deux chiffrements différents
|
||
✓ test_homomorphic_addition : Addition votes chiffrés
|
||
```
|
||
|
||
*Signatures* :
|
||
```
|
||
✓ test_sign_verify : Signature/vérification
|
||
✓ test_invalid_signature : Détection forgerie
|
||
```
|
||
|
||
*Blockchain* (`test_blockchain.py`) :
|
||
```
|
||
✓ test_blockchain_integrity : Chaîne valide
|
||
✓ test_tamper_detection : Modification détectée
|
||
✓ test_genesis_block : Bloc 0 correct
|
||
```
|
||
|
||
=== Tests d'Intégration
|
||
|
||
*Flux complet* (`test_api_fixes.py`) :
|
||
```
|
||
✓ Register → Login → Get Election → Vote → Results
|
||
✓ Double vote rejection
|
||
✓ Signature verification
|
||
```
|
||
|
||
== 8.2 Validation des Propriétés
|
||
|
||
*Confidentialité* :
|
||
```
|
||
PASS : Vote chiffré non lisible sans clé
|
||
PASS : Homomorphisme préserve confidentialité
|
||
```
|
||
|
||
*Intégrité* :
|
||
```
|
||
PASS : Modification blockchain détectée
|
||
PASS : Chaîne valide si tous blocs OK
|
||
```
|
||
|
||
*Non-Répudiation* :
|
||
```
|
||
PASS : Signature impossible sans clé privée
|
||
PASS : Clé privée secret ultime
|
||
```
|
||
|
||
= 9 Déploiement
|
||
|
||
== 9.1 Instructions Docker
|
||
|
||
```bash
|
||
# Construire
|
||
docker-compose build
|
||
|
||
# Lancer
|
||
docker-compose up -d
|
||
|
||
# Vérifier
|
||
docker-compose ps
|
||
|
||
# Logs
|
||
docker-compose logs -f backend
|
||
|
||
# Accéder
|
||
Frontend : http://localhost:3000
|
||
API docs : http://localhost:8000/docs
|
||
DB : localhost:3306
|
||
```
|
||
|
||
== 9.2 Configuration Production
|
||
|
||
- Variables d'environnement sécurisées
|
||
- HTTPS obligatoire (Let's Encrypt)
|
||
- Secrets dans `.env` chiffrés
|
||
- Nginx reverse proxy
|
||
- Backups automatiques BD
|
||
- Monitoring (Prometheus/Grafana optionnel)
|
||
|
||
#pagebreak()
|
||
|
||
= 10 Limitations et Améliorations Futures
|
||
|
||
== 10.1 Limitations Actuelles
|
||
|
||
1. *Blockchain locale* : Pas de vraie distribution (PoA optionnel)
|
||
2. *Anonymat limité* : Pas de mix networks
|
||
3. *Pas de TPM* : Clés stockées software
|
||
4. *Identité* : Demo sans vérification réelle
|
||
|
||
== 10.2 Améliorations Possibles
|
||
|
||
*Court terme* :
|
||
- Consensus PoA complet
|
||
- Audit de sécurité externe
|
||
- Tests de charge
|
||
|
||
*Moyen terme* :
|
||
- Intégration mix networks
|
||
- Preuves ZK avancées
|
||
- Frontend mobile (React Native)
|
||
|
||
*Long terme* :
|
||
- Blockchain publique (Ethereum)
|
||
- Chiffrement homomorphe complet (FHE)
|
||
- Standards internationaux (OASIS)
|
||
|
||
#pagebreak()
|
||
|
||
= 11 Conclusion
|
||
|
||
== 11.1 Réalisations
|
||
|
||
✓ Implémentation cryptographique correcte (ElGamal, RSA, Dilithium, Kyber)
|
||
✓ Architecture distribuée avec blockchain
|
||
✓ Déploiement Docker autonome
|
||
✓ Propriétés de sécurité formelles
|
||
✓ Tests complets
|
||
✓ Documentation détaillée
|
||
|
||
== 11.2 Conformité Exigences
|
||
|
||
✓ Code source complet et fonctionnel
|
||
✓ Cryptographie post-quantique hybride NIST
|
||
✓ Déploiement autonome Docker
|
||
✓ Rapport technique & scientifique
|
||
✓ Architecture adresse fraude, intimidation, anonymat
|
||
✓ Flux utilisateur complet : inscription → vote → résultats
|
||
|
||
== 11.3 Contributions Scientifiques
|
||
|
||
1. Chiffrement homomorphe appliqué au vote
|
||
2. Signatures hybrides pour quantum-resistance
|
||
3. Blockchain avec Dilithium pour immuabilité
|
||
4. Defense-in-depth cryptographique
|
||
|
||
== 11.4 Perspectives
|
||
|
||
Ce prototype démontre la faisabilité technique d'un système de vote électronique sécurisé et quantum-resistant. Les perspectives incluent :
|
||
- Audit externe
|
||
- Déploiement production avec haute disponibilité
|
||
- Standards ouverts et certification
|
||
- Intégration infrastructure gouvernementale
|
||
|
||
---
|
||
|
||
*Rapport généré : Novembre 2025*
|
||
*Système : E-Voting Post-Quantum v0.1*
|
||
*Auteurs : CIA Team*
|
||
- Vérification d'unicité des votes
|
||
- Vérification d'intégrité de la BD
|
||
|
||
== 9.3 Scénarios de Sécurité
|
||
|
||
- Attaque par replay ❌ (unique voter+election)
|
||
- Double vote ❌ (contrainte BD)
|
||
- Modification de vote ❌ (chiffrement)
|
||
- Intimdation ❌ (anonymat)
|
||
|
||
---
|
||
|
||
= 10 Limitations et Améliorations Futures
|
||
|
||
== 10.1 Limitations du Prototype
|
||
|
||
1. Paramètres ElGamal petits (prototype) - production: 2048+ bits
|
||
2. Pas de serveur de mixage - tous les votes par backend
|
||
3. Frontend sans chiffrement côté client en JavaScript
|
||
4. Pas de blockchain pour immuabilité
|
||
5. Pas de biométrie pour authentification
|
||
|
||
== 10.2 Améliorations Futures
|
||
|
||
1. *Chiffrement Paillier* pour homomorphie plus flexible
|
||
2. *Serveurs de mixage* pour anonymat renforcé
|
||
3. *Blockchain* pour immuabilité
|
||
4. *Authentification biométrique* ou 2FA
|
||
5. *Client lourd* chiffrant côté local
|
||
6. *Paramètres cryptographiques hardened*
|
||
|
||
---
|
||
|
||
= 11 Conclusion
|
||
|
||
Ce système démontre comment les concepts cryptographiques fondamentaux (chiffrement asymétrique, preuves ZK, signatures) peuvent être intégrés pour créer un système de vote sécurisé.
|
||
|
||
Les propriétés clés garanties :
|
||
- ✅ Confidentialité des votes (ElGamal)
|
||
- ✅ Intégrité (RSA-PSS, SHA-256)
|
||
- ✅ Auditabilité (journaux, preuves ZK)
|
||
- ✅ Non-coercibilité (anonymat)
|
||
|
||
Le prototype est fonctionnel, déployable, et extendable.
|
||
|
||
---
|
||
|
||
= Références
|
||
|
||
- Schneier, B. (2015). "Applied Cryptography: Protocols, Algorithms, and Source Code in C"
|
||
- ElGamal, T. (1985). "A Public Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms"
|
||
- Goldwasser, S., & Micali, S. (1984). "Probabilistic encryption & how to play mental poker keeping secret all partial information"
|
||
- NIST FIPS 186-4: "Digital Signature Standard (DSS)"
|
||
- RFC 3394: "Advanced Encryption Standard (AES) Key Wrap Algorithm"
|
||
|
||
---
|
||
|
||
#align(center)[
|
||
*Fin du rapport*
|
||
|
||
Version 1.0 - Novembre 2025
|
||
]
|