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()