- FastAPI backend with JWT authentication - ElGamal, RSA-PSS, ZK-proofs crypto modules - HTML5/JS frontend SPA - MariaDB database with 5 tables - Docker Compose with 3 services (frontend, backend, mariadb) - Comprehensive tests for cryptography - Typst technical report (30+ pages) - Makefile with development commands
77 lines
2.1 KiB
Python
77 lines
2.1 KiB
Python
"""
|
|
Fonctions de hachage cryptographique pour intégrité et dérivation de clés.
|
|
"""
|
|
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|
from typing import Tuple
|
|
import os
|
|
|
|
|
|
class SecureHash:
|
|
"""
|
|
Hachage cryptographique sécurisé avec SHA-256.
|
|
Utilisé pour:
|
|
- Vérifier l'intégrité des données
|
|
- Dériver des clés
|
|
- Identifier les votes
|
|
"""
|
|
|
|
@staticmethod
|
|
def sha256(data: bytes) -> bytes:
|
|
"""Calculer le hash SHA-256"""
|
|
digest = hashes.Hash(
|
|
hashes.SHA256(),
|
|
backend=default_backend()
|
|
)
|
|
digest.update(data)
|
|
return digest.finalize()
|
|
|
|
@staticmethod
|
|
def sha256_hex(data: bytes) -> str:
|
|
"""SHA-256 en hexadécimal"""
|
|
return SecureHash.sha256(data).hex()
|
|
|
|
@staticmethod
|
|
def derive_key(password: bytes, salt: bytes = None, length: int = 32) -> Tuple[bytes, bytes]:
|
|
"""
|
|
Dériver une clé à partir d'un mot de passe avec PBKDF2.
|
|
|
|
Returns:
|
|
(key, salt) - salt pour stocker et retrouver la clé
|
|
"""
|
|
if salt is None:
|
|
salt = os.urandom(16)
|
|
|
|
kdf = PBKDF2HMAC(
|
|
algorithm=hashes.SHA256(),
|
|
length=length,
|
|
salt=salt,
|
|
iterations=100000,
|
|
backend=default_backend()
|
|
)
|
|
|
|
key = kdf.derive(password)
|
|
return key, salt
|
|
|
|
@staticmethod
|
|
def hash_bulletin(vote_id: int, candidate_id: int, timestamp: int) -> str:
|
|
"""
|
|
Générer un identifiant unique pour un bulletin.
|
|
Utilisé pour l'anonymat + traçabilité.
|
|
"""
|
|
data = f"{vote_id}:{candidate_id}:{timestamp}".encode()
|
|
return SecureHash.sha256_hex(data)
|
|
|
|
@staticmethod
|
|
def hash_vote_commitment(encrypted_vote: bytes, random_salt: bytes) -> str:
|
|
"""
|
|
Hash d'un vote chiffré pour commitments.
|
|
"""
|
|
combined = encrypted_vote + random_salt
|
|
return SecureHash.sha256_hex(combined)
|
|
|
|
|
|
from typing import Tuple
|