Initial commit
This commit is contained in:
72
serverside/cryptography.py
Normal file
72
serverside/cryptography.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
import base64
|
||||
import ascon
|
||||
import hashlib
|
||||
import secrets
|
||||
from cryptography.hazmat.primitives.asymmetric import x25519
|
||||
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
|
||||
from cryptography.hazmat.primitives import hashes
|
||||
from typing import Tuple
|
||||
|
||||
def ascon_key_generator() -> str:
|
||||
key = os.urandom(16)
|
||||
return key.hex()
|
||||
|
||||
def encrypt(key_hex: str, plaintext: str) -> str:
|
||||
key = bytes.fromhex(key_hex)
|
||||
nonce = os.urandom(16)
|
||||
ad = b''
|
||||
|
||||
ciphertext = ascon.encrypt(key, nonce, ad, plaintext.encode(), variant="Ascon-AEAD128")
|
||||
|
||||
combined = nonce + ciphertext
|
||||
data_b64 = base64.b64encode(combined).decode()
|
||||
|
||||
return data_b64
|
||||
|
||||
def decrypt(key_hex: str, data_b64: str) -> str:
|
||||
key = bytes.fromhex(key_hex)
|
||||
combined = base64.b64decode(data_b64)
|
||||
|
||||
nonce = combined[:16]
|
||||
ciphertext = combined[16:]
|
||||
|
||||
plaintext = ascon.decrypt(key, nonce, b'', ciphertext, variant="Ascon-AEAD128")
|
||||
return plaintext.decode()
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
salt = secrets.token_hex(16)
|
||||
hashed = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100_000)
|
||||
return f"{salt}${hashed.hex()}"
|
||||
|
||||
def check_password(password: str, stored: str) -> bool:
|
||||
salt, hashed = stored.split('$')
|
||||
new_hash = hashlib.pbkdf2_hmac('sha256', password.encode(), salt.encode(), 100_000)
|
||||
return new_hash.hex() == hashed
|
||||
|
||||
def salt_randomizer() -> bytes:
|
||||
return secrets.token_bytes(32)
|
||||
|
||||
def hkdf_sha256(salt: bytes, shared_secret_raw: str) -> str:
|
||||
hkdf = HKDF(
|
||||
algorithm=hashes.SHA256(),
|
||||
length=32,
|
||||
salt=salt,
|
||||
info=b'',
|
||||
)
|
||||
key_material = hkdf.derive(shared_secret_raw)
|
||||
|
||||
return key_material
|
||||
|
||||
def compute_shared_secret(secret_key: bytes, public_key: bytes) -> bytes:
|
||||
secret_key_bytes = x25519.X25519PrivateKey.from_private_bytes(secret_key)
|
||||
public_key_bytes = x25519.X25519PublicKey.from_public_bytes(public_key)
|
||||
|
||||
shared_secret_raw = secret_key_bytes.exchange(public_key_bytes)
|
||||
|
||||
return shared_secret_raw
|
||||
|
||||
def generate_keypair() -> Tuple[x25519.X25519PrivateKey, x25519.X25519PublicKey]:
|
||||
secret_key_bytes = x25519.X25519PrivateKey.generate()
|
||||
public_key_bytes = secret_key_bytes.public_key()
|
||||
return secret_key_bytes, public_key_bytes
|
||||
Reference in New Issue
Block a user