from __future__ import annotations import os import unittest from cmbuyer_client.core.errors import ProtectionError from cmbuyer_client.localstate.protection import DpapiProtector @unittest.skipUnless(os.name == "nt", "DPAPI 仅在 Windows 验证") class DpapiProtectorTests(unittest.TestCase): def test_current_user_round_trip_purpose_isolation_and_corruption(self) -> None: protector = DpapiProtector() plaintext = b"a" * 64 device_purpose = "device-token:default:33c9f507-7473-4fa6-8d71-8786c34c6301" claim_purpose = "claim-token:default:53c9f507-7473-4fa6-8d71-8786c34c6301" ciphertext = protector.protect(plaintext, purpose=device_purpose) self.assertNotIn(plaintext, ciphertext) self.assertEqual(protector.unprotect(ciphertext, purpose=device_purpose), plaintext) with self.assertRaises(ProtectionError): protector.unprotect(ciphertext, purpose=claim_purpose) damaged = ciphertext[:-1] + bytes((ciphertext[-1] ^ 1,)) with self.assertRaises(ProtectionError): protector.unprotect(damaged, purpose=device_purpose)