55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
import unittest
|
|
|
|
|
|
from app.core import api_crypto
|
|
|
|
|
|
class ApiCryptoTests(unittest.TestCase):
|
|
def test_derive_key_is_stable_for_same_input(self):
|
|
key1 = api_crypto.derive_key(
|
|
fixed_secret="fixed-secret",
|
|
user_id="u1",
|
|
ts=1714300000000,
|
|
nonce="nonce-1",
|
|
)
|
|
key2 = api_crypto.derive_key(
|
|
fixed_secret="fixed-secret",
|
|
user_id="u1",
|
|
ts=1714300000000,
|
|
nonce="nonce-1",
|
|
)
|
|
self.assertEqual(key1, key2)
|
|
self.assertEqual(len(key1), 32)
|
|
|
|
def test_encrypt_decrypt_roundtrip(self):
|
|
key = api_crypto.derive_key(
|
|
fixed_secret="fixed-secret",
|
|
user_id="u1",
|
|
ts=1714300000000,
|
|
nonce="nonce-1",
|
|
)
|
|
payload = {"a": 1, "b": "x"}
|
|
cipher = api_crypto.encrypt_json(payload, key)
|
|
plain = api_crypto.decrypt_json(cipher, key)
|
|
self.assertEqual(plain, payload)
|
|
|
|
def test_decrypt_rejects_tampered_gcm_ciphertext(self):
|
|
key = api_crypto.derive_key(
|
|
fixed_secret="fixed-secret",
|
|
user_id="u1",
|
|
ts=1714300000000,
|
|
nonce="nonce-2",
|
|
)
|
|
payload = {"list": [1, 2, 3], "ok": True}
|
|
cipher = api_crypto.encrypt_json(payload, key)
|
|
raw = bytearray(api_crypto._b64url_decode(cipher))
|
|
raw[-1] ^= 1
|
|
tampered = api_crypto._b64url_encode(bytes(raw))
|
|
|
|
with self.assertRaises(api_crypto.ApiCryptoError):
|
|
api_crypto.decrypt_json(tampered, key)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|