security(07.3-02): ES256 signing — swap 4 JWT sites + config keys + promote tests

- backend/config.py: add refresh_token_expire_hours=16, jwt_private_key, jwt_public_key
- backend/services/auth.py: add import base64; all 4 JWT sites use ES256 with inline PEM decode; zero HS256/secret_key references
- backend/tests/test_auth_es256.py: promote ES256-01..03 + CFG-01 tests from xfail to passing
This commit is contained in:
curo1305
2026-06-06 16:59:38 +02:00
parent 1eb1d59c8d
commit fd3f611546
3 changed files with 53 additions and 14 deletions
+9 -4
View File
@@ -17,6 +17,7 @@ Security invariants:
"""
from __future__ import annotations
import base64
import hashlib
import hmac
import logging
@@ -97,7 +98,8 @@ def create_access_token(user_id: str, role: str) -> str:
"exp": now + timedelta(minutes=settings.access_token_expire_minutes),
"jti": str(uuid.uuid4()),
}
return jwt.encode(payload, settings.secret_key, algorithm="HS256")
private_pem = base64.b64decode(settings.jwt_private_key).decode()
return jwt.encode(payload, private_pem, algorithm="ES256")
def decode_access_token(token: str) -> dict:
@@ -107,7 +109,8 @@ def decode_access_token(token: str) -> dict:
tokens from being used as access tokens).
"""
try:
payload = jwt.decode(token, settings.secret_key, algorithms=["HS256"])
public_pem = base64.b64decode(settings.jwt_public_key).decode()
payload = jwt.decode(token, public_pem, algorithms=["ES256"])
except jwt.ExpiredSignatureError as exc:
raise ValueError("Token has expired") from exc
except jwt.PyJWTError as exc:
@@ -130,7 +133,8 @@ def create_password_reset_token(user_id: str) -> str:
"iat": now,
"exp": now + timedelta(seconds=3600),
}
return jwt.encode(payload, settings.secret_key, algorithm="HS256")
private_pem = base64.b64decode(settings.jwt_private_key).decode()
return jwt.encode(payload, private_pem, algorithm="ES256")
def decode_password_reset_token(token: str) -> str:
@@ -139,7 +143,8 @@ def decode_password_reset_token(token: str) -> str:
Returns the user_id string.
"""
try:
payload = jwt.decode(token, settings.secret_key, algorithms=["HS256"])
public_pem = base64.b64decode(settings.jwt_public_key).decode()
payload = jwt.decode(token, public_pem, algorithms=["ES256"])
except jwt.ExpiredSignatureError as exc:
raise ValueError("Reset token has expired") from exc
except jwt.PyJWTError as exc: