mirror of
https://github.com/ae-utbm/sith.git
synced 2025-06-07 19:55:20 +00:00
44 lines
1.2 KiB
Python
44 lines
1.2 KiB
Python
import functools
|
|
import hashlib
|
|
import secrets
|
|
|
|
from django.contrib.auth.hashers import BasePasswordHasher
|
|
from django.utils.crypto import constant_time_compare
|
|
|
|
|
|
class Sha512ApiKeyHasher(BasePasswordHasher):
|
|
"""
|
|
An API key hasher using the sha256 algorithm.
|
|
|
|
This hasher shouldn't be used in Django's `PASSWORD_HASHERS` setting.
|
|
It is insecure for use in hashing passwords, but is safe for hashing
|
|
high entropy, randomly generated API keys.
|
|
"""
|
|
|
|
algorithm = "sha512"
|
|
|
|
def salt(self) -> str:
|
|
# No need for a salt on a high entropy key.
|
|
return ""
|
|
|
|
def encode(self, password: str, salt: str = "") -> str:
|
|
hashed = hashlib.sha512(password.encode()).hexdigest()
|
|
return f"{self.algorithm}$${hashed}"
|
|
|
|
def verify(self, password: str, encoded: str) -> bool:
|
|
encoded_2 = self.encode(password, "")
|
|
return constant_time_compare(encoded, encoded_2)
|
|
|
|
|
|
@functools.cache
|
|
def get_hasher():
|
|
return Sha512ApiKeyHasher()
|
|
|
|
|
|
def generate_key() -> tuple[str, str]:
|
|
"""Generate a [key, hash] couple."""
|
|
# this will result in key with a length of 72
|
|
key = str(secrets.token_urlsafe(54))
|
|
hasher = get_hasher()
|
|
return key, hasher.encode(key)
|