mirror of
https://github.com/ae-utbm/sith.git
synced 2025-06-07 11:45:20 +00:00
use 54 bytes keys and sha512 hashing
This commit is contained in:
parent
2dd28a37ab
commit
e765fcc96e
@ -4,14 +4,12 @@ from ninja.security import APIKeyHeader
|
||||
from apikey.hashers import get_hasher
|
||||
from apikey.models import ApiClient, ApiKey
|
||||
|
||||
_UUID_LENGTH = 36
|
||||
|
||||
|
||||
class ApiKeyAuth(APIKeyHeader):
|
||||
param_name = "X-APIKey"
|
||||
|
||||
def authenticate(self, request: HttpRequest, key: str | None) -> ApiClient | None:
|
||||
if not key or len(key) != _UUID_LENGTH:
|
||||
if not key or len(key) != ApiKey.KEY_LENGTH:
|
||||
return None
|
||||
hasher = get_hasher()
|
||||
hashed_key = hasher.encode(key)
|
||||
|
@ -1,12 +1,12 @@
|
||||
import functools
|
||||
import hashlib
|
||||
import uuid
|
||||
import secrets
|
||||
|
||||
from django.contrib.auth.hashers import BasePasswordHasher
|
||||
from django.utils.crypto import constant_time_compare
|
||||
|
||||
|
||||
class Sha256ApiKeyHasher(BasePasswordHasher):
|
||||
class Sha512ApiKeyHasher(BasePasswordHasher):
|
||||
"""
|
||||
An API key hasher using the sha256 algorithm.
|
||||
|
||||
@ -15,14 +15,14 @@ class Sha256ApiKeyHasher(BasePasswordHasher):
|
||||
high entropy, randomly generated API keys.
|
||||
"""
|
||||
|
||||
algorithm = "sha256"
|
||||
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.sha256(password.encode()).hexdigest()
|
||||
hashed = hashlib.sha512(password.encode()).hexdigest()
|
||||
return f"{self.algorithm}$${hashed}"
|
||||
|
||||
def verify(self, password: str, encoded: str) -> bool:
|
||||
@ -32,11 +32,12 @@ class Sha256ApiKeyHasher(BasePasswordHasher):
|
||||
|
||||
@functools.cache
|
||||
def get_hasher():
|
||||
return Sha256ApiKeyHasher()
|
||||
return Sha512ApiKeyHasher()
|
||||
|
||||
|
||||
def generate_key() -> tuple[str, str]:
|
||||
"""Generate a [key, hash] couple."""
|
||||
key = str(uuid.uuid4())
|
||||
# this will result in key with a length of 72
|
||||
key = str(secrets.token_urlsafe(54))
|
||||
hasher = get_hasher()
|
||||
return key, hasher.encode(key)
|
||||
|
@ -88,7 +88,7 @@ class Migration(migrations.Migration):
|
||||
models.CharField(
|
||||
db_index=True,
|
||||
editable=False,
|
||||
max_length=150,
|
||||
max_length=136,
|
||||
verbose_name="hashed key",
|
||||
),
|
||||
),
|
||||
|
@ -17,9 +17,7 @@ class ApiClient(models.Model):
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
groups = models.ManyToManyField(
|
||||
Group,
|
||||
verbose_name=_("groups"),
|
||||
related_name="api_clients",
|
||||
Group, verbose_name=_("groups"), related_name="api_clients", blank=True
|
||||
)
|
||||
client_permissions = models.ManyToManyField(
|
||||
Permission,
|
||||
@ -70,11 +68,13 @@ class ApiClient(models.Model):
|
||||
|
||||
class ApiKey(models.Model):
|
||||
PREFIX_LENGTH = 5
|
||||
KEY_LENGTH = 72
|
||||
HASHED_KEY_LENGTH = 136
|
||||
|
||||
name = models.CharField(_("name"), blank=True, default="")
|
||||
prefix = models.CharField(_("prefix"), max_length=PREFIX_LENGTH, editable=False)
|
||||
hashed_key = models.CharField(
|
||||
_("hashed key"), max_length=150, db_index=True, editable=False
|
||||
_("hashed key"), max_length=HASHED_KEY_LENGTH, db_index=True, editable=False
|
||||
)
|
||||
client = models.ForeignKey(
|
||||
ApiClient,
|
||||
|
Loading…
x
Reference in New Issue
Block a user