98 lines
2.8 KiB
Python

"""
Signatures numériques pour authentification et non-répudiation.
"""
from cryptography.hazmat.primitives.asymmetric import rsa, padding, utils
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.backends import default_backend
import os
from typing import Tuple
class DigitalSignature:
"""
Signatures RSA-PSS pour authentification et non-répudiation.
Propriétés:
- Non-répudiation (l'auteur ne peut pas nier)
- Authentification de l'origine
- Intégrité des données
"""
def __init__(self, key_size: int = 2048):
self.key_size = key_size
self.backend = default_backend()
def generate_keypair(self) -> Tuple[bytes, bytes]:
"""
Générer une paire de clés RSA.
Returns:
(private_key_pem, public_key_pem)
"""
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=self.key_size,
backend=self.backend
)
private_pem = private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.PKCS8,
encryption_algorithm=serialization.NoEncryption()
)
public_pem = private_key.public_key().public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
return private_pem, public_pem
def sign(self, private_key_pem: bytes, message: bytes) -> bytes:
"""
Signer un message avec la clé privée.
"""
private_key = serialization.load_pem_private_key(
private_key_pem,
password=None,
backend=self.backend
)
signature = private_key.sign(
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return signature
def verify(self, public_key_pem: bytes, message: bytes, signature: bytes) -> bool:
"""
Vérifier la signature d'un message.
Returns:
True si la signature est valide, False sinon
"""
try:
public_key = serialization.load_pem_public_key(
public_key_pem,
backend=self.backend
)
public_key.verify(
signature,
message,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
return True
except Exception:
return False