48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
import hashlib
|
|
from cryptography.hazmat.primitives import hashes
|
|
from cryptography.hazmat.primitives.asymmetric import rsa
|
|
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicKey
|
|
from cryptography.hazmat.primitives.asymmetric import padding
|
|
|
|
|
|
class Card:
|
|
"""
|
|
Represent the card of an elector.
|
|
"""
|
|
|
|
def __init__(self, pin: str):
|
|
self._private_key = rsa.generate_private_key(
|
|
public_exponent=65537,
|
|
key_size=2048,
|
|
)
|
|
self.public_key: RSAPublicKey = self._private_key.public_key()
|
|
|
|
digest = hashes.Hash(hashes.SHA256())
|
|
digest.update(bytes(pin, 'utf-8'))
|
|
self.hashed_pin = digest.finalize()
|
|
# self.activee = False
|
|
|
|
def check_pin(self, hashed_pin: bytes) -> bool:
|
|
"""
|
|
Check if the card is valid by comparing hashed PIN.
|
|
:param hashed_pin: 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
|