import hashlib from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import padding class Card: """ Represent the card of an elector. """ def __init__(self, name: str, pin: int): self.name = name self.private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, ) self._public_key = self.private_key.public_key() digest = hashes.Hash(hashes.SHA256()) digest.update(pin.to_bytes()) self.hashed_pin = digest.finalize() # self.activee = False @property def public_key(self): return self._public_key def check_pin(self, hashed_pin: bytes) -> bool: """ Check if the card is valid by comparing hashed PIN. :param pin_hash: The PIN to check. :return: True if the received hash PIN matches the stored hashed PIN, False otherwise. """ return self.hashed_pin == hashed_pin # NOTE(Faraphel): a PKI or a banlist / whitelist shall be checked with self.public_key def reply_challenge(self, data: bytes = "encrypted data") -> bytes: """ :param data: The challeng sent by the terminal to sign. :return: The signed challenge. """ signature = self.private_key.sign( data, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) return signature