""" Тесты криптографического журнала IssLedger117: - Проверка непрерывности цепочки ГОСТ Р 34.11-2012 - Выявление попыток фальсификации (Tamper Detection) - Проверка выявления удаления или подмены строк """ import os import shutil import tempfile import unittest from iss_ledger_117 import IssLedger117, GENESIS_PREV_HASH class TestIssLedger117(unittest.TestCase): def setUp(self): self.test_dir = tempfile.mkdtemp() self.ledger_path = os.path.join(self.test_dir, "test_audit.jsonl") self.ledger = IssLedger117(self.ledger_path) def tearDown(self): shutil.rmtree(self.test_dir, ignore_errors=True) def test_append_and_verify_valid_chain(self): """Проверка корректной генерации цепочки из 10 записей.""" for i in range(10): entry = self.ledger.append( agent_id=f"agent-0{i%3}", action="tool_call:sql", target="db.prod.billing", verdict="PERMIT" if i % 2 == 0 else "BLOCK", reason="Policy approved" if i % 2 == 0 else "Нарушен инвариант: DROP TABLE prohibited", payload={"query": f"SELECT * FROM tbl_{i}"} ) self.assertEqual(entry["index"], i + 1) self.assertEqual(len(entry["entry_hash"]), 64) is_valid, count, msg = self.ledger.verify() self.assertTrue(is_valid) self.assertEqual(count, 10) self.assertIn("успешно подтверждена", msg) def test_tamper_payload_detection(self): """Проверка детекции подмены 1 символа в теле записи.""" # Добавляем 5 записей for i in range(5): self.ledger.append( agent_id="claude-code", action="tool_call:fs_read", target=f"/etc/app/config_{i}.json", verdict="PERMIT" ) # Читаем строки и модифицируем 3-ю запись with open(self.ledger_path, "r", encoding="utf-8") as f: lines = f.readlines() # Фальсифицируем вердикт с PERMIT на BLOCK или меняем 1 букву tampered_line = lines[2].replace("PERMIT", "BLOCK") lines[2] = tampered_line with open(self.ledger_path, "w", encoding="utf-8") as f: f.writelines(lines) # Проверяем верификатором is_valid, failed_line, msg = self.ledger.verify() self.assertFalse(is_valid) self.assertEqual(failed_line, 3) self.assertIn("ФАЛЬСИФИКАЦИЯ ДАННЫХ", msg) def test_deleted_line_detection(self): """Проверка детекции скрытого удаления строки злоумышленником.""" for i in range(5): self.ledger.append( agent_id="cursor-agent", action="tool_call:bash", target="make build", verdict="PERMIT" ) # Читаем строки и удаляем 2-ю запись with open(self.ledger_path, "r", encoding="utf-8") as f: lines = f.readlines() del lines[1] # Удаляем запись #2 with open(self.ledger_path, "w", encoding="utf-8") as f: f.writelines(lines) is_valid, failed_line, msg = self.ledger.verify() self.assertFalse(is_valid) self.assertEqual(failed_line, 2) self.assertIn("Нарушение нумерации", msg) if __name__ == "__main__": unittest.main()