diff --git a/.idea/libraries/bytedeco_javacv_platform.xml b/.idea/libraries/bytedeco_javacv_platform.xml index 9fa3834..53085a2 100644 --- a/.idea/libraries/bytedeco_javacv_platform.xml +++ b/.idea/libraries/bytedeco_javacv_platform.xml @@ -19,9 +19,9 @@ - + - + diff --git a/databases.json b/databases.json index 3f862b5..7a73a41 100644 --- a/databases.json +++ b/databases.json @@ -1,3 +1,2 @@ { - "esffs": "e4aebaf0f1b173cdf19ae33a5539cc4e52990f37473f6f41623e1a3a346fa713" } \ No newline at end of file diff --git a/src/Classes/DatabasesManager.java b/src/Classes/DatabasesManager.java index 284d52f..35e22c0 100644 --- a/src/Classes/DatabasesManager.java +++ b/src/Classes/DatabasesManager.java @@ -14,38 +14,44 @@ public class DatabasesManager { private final File databasesFile; - private final Map databases; - Sha256 sha256 = new Sha256(); + private final Map databases; + private final Sha256 sha256 = new Sha256(); + public DatabasesManager(File databasesFile) { this.databasesFile = databasesFile; - this.databases = loadDatabases(); + this.databases = loadDatabases() != null ? loadDatabases() : new HashMap<>(); } public boolean verifyDatabase(String dbName, String password) { + if (!databases.containsKey(dbName)) return false; + Database database = databases.get(dbName); String hashedPassword = sha256.calculateHash(password); - return databases.containsKey(dbName) && databases.get(dbName).equals(hashedPassword); + return database.getHashPassword().equals(hashedPassword); } - public void createDatabase(String dbName, String password) { + public void createDatabase(String dbName, String password, Map encryptionMap) { if (databases.containsKey(dbName)) { throw new IllegalArgumentException("Database already exists."); } String hashedPassword = sha256.calculateHash(password); - databases.put(dbName, hashedPassword); + Database newDatabase = new Database(dbName, hashedPassword, encryptionMap); + databases.put(dbName, newDatabase); saveDatabases(); } - public Map loadDatabases() { + private Map loadDatabases() { if (!databasesFile.exists()) return new HashMap<>(); try (FileReader reader = new FileReader(databasesFile)) { Gson gson = new Gson(); - Type type = new TypeToken>() {}.getType(); + Type type = new TypeToken>() {}.getType(); return gson.fromJson(reader, type); } catch (IOException e) { + e.printStackTrace(); return new HashMap<>(); } } + private void saveDatabases() { try (FileWriter writer = new FileWriter(databasesFile)) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); @@ -54,4 +60,43 @@ private void saveDatabases() { e.printStackTrace(); } } + + // Classe interne représentant une base de données + public static class Database { + private final String name; + private final String hashPassword; + private final Map encryptionMap; + + public Database(String name, String hashPassword, Map encryptionMap) { + this.name = name; + this.hashPassword = hashPassword; + this.encryptionMap = encryptionMap; + } + + public String getName() { + return name; + } + + public String getHashPassword() { + return hashPassword; + } + + public Map getEncryptionMap() { + return encryptionMap; + } + } + public Map getEncryptionMap(String dbName) { + if (!databases.containsKey(dbName)) { + throw new IllegalArgumentException("Database does not exist: " + dbName); + } + try (FileReader reader = new FileReader(databasesFile)) { + Gson gson = new Gson(); + Map> allDatabases = gson.fromJson(reader, Map.class); + Map dbData = allDatabases.get(dbName); + return (Map) dbData.get("encryptionMap"); + } catch (IOException e) { + throw new RuntimeException("Failed to read databases file.", e); + } + } + } diff --git a/src/Classes/HelpMenu.java b/src/Classes/HelpMenu.java index a527dcc..807028c 100644 --- a/src/Classes/HelpMenu.java +++ b/src/Classes/HelpMenu.java @@ -42,6 +42,7 @@ public static void displayMenuHelp(Scanner scanner) { break; case 6: System.out.println("Exiting help menu..."); // Exit message. + Menu.main(null); // Return to the main menu. break; default: System.out.println("Invalid choice. Please select a valid option."); // Handle invalid input. diff --git a/src/Classes/Menu.java b/src/Classes/Menu.java index 3d406cf..4be04d6 100644 --- a/src/Classes/Menu.java +++ b/src/Classes/Menu.java @@ -1,6 +1,7 @@ package Classes; import java.io.File; +import java.util.HashMap; import java.util.Map; import java.util.Scanner; @@ -33,8 +34,12 @@ public static void main(String[] args) { // Verify the database credentials if (dbManager.verifyDatabase(dbName, inputPassword)) { System.out.println("Successfully connected to the database: " + dbName); + + // Retrieve the encryption map for the database + Map encryptionMap = dbManager.getEncryptionMap(dbName); + // Initialize the SiteManager to manage sites within the database - SiteManager siteManager = new SiteManager(new File(dbName + ".json")); + SiteManager siteManager = new SiteManager(new File(dbName + ".json"), encryptionMap); siteManager.manageSites(scanner); // Begin managing sites } else { System.out.println("Incorrect database name or password."); // Error message for invalid credentials @@ -58,14 +63,55 @@ else if (dbChoice == 2) { : PasswordUtils.generateRandomPassword(12); // Generate a random password System.out.println("Generated password: " + password); - // Create the new database with the given name and password - dbManager.createDatabase(dbName, password); + + // Ask the user for encryption methods + Map encryptionMap = new HashMap<>(); + boolean addMoreEncryptions = true; + + while (addMoreEncryptions) { + System.out.println("Choose an encryption method:"); + System.out.println("1. RotX"); + System.out.println("2. RC4"); + System.out.println("3. Vigenere"); + System.out.println("4. Polybios"); + System.out.println("5. Done adding encryptions"); + + int encryptionChoice = scanner.nextInt(); + scanner.nextLine(); // Consume newline character + + switch (encryptionChoice) { + case 1 -> { + System.out.println("Enter the shift value for RotX:"); + String shiftValue = scanner.nextLine(); + encryptionMap.put("RotX", shiftValue); + } + case 2 -> { + System.out.println("Enter the key for RC4:"); + String rc4Key = scanner.nextLine(); + encryptionMap.put("RC4", rc4Key); + } + case 3 -> { + System.out.println("Enter the key for Vigenere:"); + String vigenereKey = scanner.nextLine(); + encryptionMap.put("Vigenere", vigenereKey); + } + case 4 -> { + encryptionMap.put("Polybios", "default"); + } + case 5 -> addMoreEncryptions = false; + default -> System.out.println("Invalid choice. Please choose a valid encryption method."); + } + } + + // Create the new database with the given name, password, and encryption map + dbManager.createDatabase(dbName, password, encryptionMap); + // Initialize the SiteManager for the new database - SiteManager siteManager = new SiteManager(new File(dbName + ".json")); + SiteManager siteManager = new SiteManager(new File(dbName + ".json"), encryptionMap); siteManager.manageSites(scanner); // Begin managing sites } // Handle the case where the user wants to access the help menu - else if (dbChoice == 3){ + else if (dbChoice == 3) { HelpMenu.displayMenuHelp(scanner); // Display the help menu } // Handle invalid choices diff --git a/src/Classes/SiteManager.java b/src/Classes/SiteManager.java index a5e8bcc..718c67a 100644 --- a/src/Classes/SiteManager.java +++ b/src/Classes/SiteManager.java @@ -12,9 +12,11 @@ public class SiteManager { private final File dbFile; private final List> sites; + private final Map encryptionMap; // Méthodes de chiffrement associées - public SiteManager(File dbFile) { + public SiteManager(File dbFile, Map encryptionMap) { this.dbFile = dbFile; + this.encryptionMap = encryptionMap; this.sites = loadSites(); } @@ -24,7 +26,8 @@ public void manageSites(Scanner scanner) { System.out.println("1. Add a site"); System.out.println("2. Modify a site"); System.out.println("3. Delete a site"); - System.out.println("4. Exit"); + System.out.println("4. Display all sites"); + System.out.println("5. Exit"); int choice = scanner.nextInt(); scanner.nextLine(); @@ -32,14 +35,18 @@ public void manageSites(Scanner scanner) { case 1 -> addSite(scanner); case 2 -> modifySite(scanner); case 3 -> deleteSite(scanner); - case 4 -> { return; } + case 4 -> displaySites(); + case 5 -> { return; } default -> System.out.println("Invalid choice."); } } } public void addSite(String siteName, String username, String password) { - Map site = Map.of("siteName", siteName, "username", username, "password", password); + Map site = new HashMap<>(); + site.put("siteName", siteName); + site.put("username", username); + site.put("password", password); sites.add(site); saveSites(); } @@ -63,12 +70,10 @@ public void modifySite(String siteName, String newUsername, String newPassword) if (newPassword != null && !newPassword.isEmpty()) { site.put("password", newPassword); } - System.out.println("Modified site: " + site); saveSites(); return; } } - System.out.println("Site not found for modification: " + siteName); throw new IllegalArgumentException("Site not found: " + siteName); } @@ -82,7 +87,6 @@ public void modifySite(Scanner scanner) { modifySite(siteName, newUsername, newPassword); } - public void deleteSite(String siteName) { sites.removeIf(site -> site.get("siteName").equals(siteName)); saveSites(); @@ -94,25 +98,116 @@ public void deleteSite(Scanner scanner) { deleteSite(siteName); } + public void displaySites() { + if (sites.isEmpty()) { + System.out.println("No sites available."); + } else { + for (Map site : sites) { + String siteName = site.get("siteName"); + String username = site.get("username"); + String password = site.get("password"); + System.out.println("Site Name: " + siteName); + System.out.println("Username: " + username); + System.out.println("Password: " + password); + System.out.println("-----------------------------"); + } + } + } public List> loadSites() { if (!dbFile.exists()) return new ArrayList<>(); try (FileReader reader = new FileReader(dbFile)) { + // Lire le fichier et déchiffrer son contenu + StringBuilder encryptedContent = new StringBuilder(); + int c; + while ((c = reader.read()) != -1) { + encryptedContent.append((char) c); + } + + // Déchiffrement du contenu entier + String decryptedContent = decrypt(encryptedContent.toString()); + Gson gson = new Gson(); - Map data = gson.fromJson(reader, Map.class); + Map data = gson.fromJson(decryptedContent, Map.class); return (List>) data.get("sites"); } catch (IOException e) { + e.printStackTrace(); return new ArrayList<>(); } } public void saveSites() { try (FileWriter writer = new FileWriter(dbFile)) { + // Conversion des sites en JSON Gson gson = new GsonBuilder().setPrettyPrinting().create(); Map data = Map.of("sites", sites); - gson.toJson(data, writer); + String jsonContent = gson.toJson(data); + + // Chiffrer le contenu JSON + String encryptedContent = encrypt(jsonContent); + + writer.write(encryptedContent); } catch (IOException e) { e.printStackTrace(); } } + + private String encrypt(String input) { + String result = input; + for (String method : encryptionMap.keySet()) { + switch (method) { + case "RotX" -> { + int shift = Integer.parseInt(encryptionMap.get("RotX")); + result = ROTX.encryptROT(result, shift); + } + case "RC4" -> { + RC4 rc4 = new RC4(); + String key = encryptionMap.get("RC4"); + rc4.init(key); + result = rc4.encrypt(result); + } + case "Vigenere" -> { + String key = encryptionMap.get("Vigenere"); + result = VigenereAlgo.encrypt(result, key); + } + case "Polybios" -> { + } + case "AES" -> { + } + } + } + return result; + } + + private String decrypt(String input) { + String result = input; + // Inverser l'ordre des méthodes pour le déchiffrement + List methods = new ArrayList<>(encryptionMap.keySet()); + Collections.reverse(methods); + + for (String method : methods) { + switch (method) { + case "RotX" -> { + int shift = Integer.parseInt(encryptionMap.get("RotX")); + result = ROTX.decryptROT(result, shift); + } + case "RC4" -> { + RC4 rc4 = new RC4(); + String key = encryptionMap.get("RC4"); + rc4.init(key); + result = rc4.decrypt(result); + } + case "Vigenere" -> { + String key = encryptionMap.get("Vigenere"); + result = VigenereAlgo.decrypt(result, key); + } + case "Polybios" -> { + } + case "AES" -> { + } + } + } + return result; + } + } diff --git a/src/Tests/DatabasesManagerTest.java b/src/Tests/DatabasesManagerTest.java index b2f098b..b4d837e 100644 --- a/src/Tests/DatabasesManagerTest.java +++ b/src/Tests/DatabasesManagerTest.java @@ -1,58 +1,109 @@ package Tests; import Classes.DatabasesManager; -import org.junit.Before; -import org.junit.Test; +import Classes.Sha256; +import org.junit.*; +import static org.junit.Assert.*; import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.*; - public class DatabasesManagerTest { - private DatabasesManager dbManager; - private File testFile; + + private static File testFile; + private DatabasesManager manager; + + @BeforeClass + public static void setUpBeforeClass() throws IOException { + testFile = new File("testDatabases.json"); + if (testFile.exists()) { + testFile.delete(); + } + testFile.createNewFile(); + } + + @AfterClass + public static void tearDownAfterClass() { + if (testFile.exists()) { + testFile.delete(); + } + } @Before public void setUp() { - testFile = new File("src/Tests/assets/test_databases.json"); - dbManager = new DatabasesManager(testFile); + manager = new DatabasesManager(testFile); + } + @After + public void tearDown() { if (testFile.exists()) { testFile.delete(); } } @Test - public void testCreateAndVerifyDatabase() { - String dbName = "testDb"; - String password = "securePassword"; + public void testCreateDatabase() { + String dbName = "TestDB"; + String password = "password123"; + Map encryptionMap = new HashMap<>(); + encryptionMap.put("key1", "value1"); + + manager.createDatabase(dbName, password, encryptionMap); - dbManager.createDatabase(dbName, password); + assertTrue(manager.verifyDatabase(dbName, password)); + assertEquals(encryptionMap, manager.getEncryptionMap(dbName)); + } - assertTrue(dbManager.verifyDatabase(dbName, password)); + @Test(expected = IllegalArgumentException.class) + public void testCreateDatabaseDuplicate() { + String dbName = "TestDB"; + String password = "password123"; + Map encryptionMap = new HashMap<>(); - assertFalse(dbManager.verifyDatabase(dbName, "wrongPassword")); + manager.createDatabase(dbName, password, encryptionMap); + manager.createDatabase(dbName, password, encryptionMap); } @Test - public void testDuplicateDatabaseName() { - String dbName = "duplicateDb"; - String password = "password"; + public void testVerifyDatabase() { + String dbName = "TestDB"; + String password = "password123"; + Map encryptionMap = new HashMap<>(); - dbManager.createDatabase(dbName, password); + manager.createDatabase(dbName, password, encryptionMap); - try { - dbManager.createDatabase(dbName, password); - fail("Expected IllegalArgumentException for duplicate database name"); - } catch (IllegalArgumentException e) { - assertEquals("Database already exists.", e.getMessage()); - } + assertTrue(manager.verifyDatabase(dbName, password)); + assertFalse(manager.verifyDatabase(dbName, "wrongPassword")); + assertFalse(manager.verifyDatabase("NonExistentDB", password)); } @Test - public void testLoadEmptyDatabases() { - Map databases = dbManager.loadDatabases(); - assertTrue(databases.isEmpty()); + public void testLoadDatabases() throws IOException { + // Pre-populate the test file with data + String dbName = "TestDB"; + Sha256 sha256 = new Sha256(); + String passwordHash = sha256 .calculateHash("password123"); + Map encryptionMap = new HashMap<>(); + encryptionMap.put("key1", "value1"); + + Map preloadedData = new HashMap<>(); + preloadedData.put(dbName, new DatabasesManager.Database(dbName, passwordHash, encryptionMap)); + + try (FileWriter writer = new FileWriter(testFile)) { + writer.write(new com.google.gson.GsonBuilder().setPrettyPrinting().create().toJson(preloadedData)); + } + + manager = new DatabasesManager(testFile); + + assertTrue(manager.verifyDatabase(dbName, "password123")); + assertEquals(encryptionMap, manager.getEncryptionMap(dbName)); + } + + @Test(expected = IllegalArgumentException.class) + public void testGetEncryptionMapForNonExistentDatabase() { + manager.getEncryptionMap("NonExistentDB"); } } diff --git a/src/Tests/SiteManagerTest.java b/src/Tests/SiteManagerTest.java index 8dc1e9a..7401f95 100644 --- a/src/Tests/SiteManagerTest.java +++ b/src/Tests/SiteManagerTest.java @@ -1,61 +1,89 @@ -package Tests; - -import Classes.SiteManager; -import org.junit.Before; -import org.junit.Test; +package Classes; +import org.junit.*; import java.io.File; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.junit.Assert.*; public class SiteManagerTest { + + private File tempFile; private SiteManager siteManager; - private File testFile; @Before public void setUp() { - testFile = new File("src/Tests/assets/test_sites.json"); - siteManager = new SiteManager(testFile); + tempFile = new File("test_db.json"); + Map encryptionMap = Map.of("RotX", "3"); // Exemple de méthode de chiffrement + siteManager = new SiteManager(tempFile, encryptionMap); + } - if (testFile.exists()) { - testFile.delete(); + @After + public void tearDown() { + if (tempFile.exists()) { + tempFile.delete(); } } @Test public void testAddSite() { - siteManager.addSite("example.com", "user1", "password1"); - List> sites = siteManager.loadSites(); + siteManager.addSite("example.com", "user123", "pass123"); + List> sites = siteManager.loadSites(); assertEquals(1, sites.size()); - assertEquals("example.com", sites.get(0).get("siteName")); - assertEquals("user1", sites.get(0).get("username")); - assertEquals("password1", sites.get(0).get("password")); + + Map site = sites.get(0); + assertEquals("example.com", site.get("siteName")); + assertEquals("user123", site.get("username")); + assertEquals("pass123", site.get("password")); } @Test public void testModifySite() { - siteManager.modifySite("example.com", "newUser", "newPassword"); + siteManager.addSite("example.com", "user123", "pass123"); + siteManager.modifySite("example.com", "newUser", "newPass"); List> sites = siteManager.loadSites(); - - System.out.println("Sites after modification: " + sites); - assertEquals(1, sites.size()); - assertEquals("newUser", sites.get(0).get("username")); - assertEquals("newPassword", sites.get(0).get("password")); - } + Map site = sites.get(0); + assertEquals("example.com", site.get("siteName")); + assertEquals("newUser", site.get("username")); + assertEquals("newPass", site.get("password")); + } @Test public void testDeleteSite() { - siteManager.addSite("example.com", "user1", "password1"); + siteManager.addSite("example.com", "user123", "pass123"); siteManager.deleteSite("example.com"); List> sites = siteManager.loadSites(); - assertTrue(sites.isEmpty()); } + + @Test + public void testLoadSites() { + siteManager.addSite("example.com", "user123", "pass123"); + siteManager.addSite("test.com", "testUser", "testPass"); + + List> sites = siteManager.loadSites(); + assertEquals(2, sites.size()); + + Map site1 = sites.get(0); + Map site2 = sites.get(1); + + assertEquals("example.com", site1.get("siteName")); + assertEquals("user123", site1.get("username")); + assertEquals("pass123", site1.get("password")); + + assertEquals("test.com", site2.get("siteName")); + assertEquals("testUser", site2.get("username")); + assertEquals("testPass", site2.get("password")); + } + + @Test + public void testDisplaySites() { + siteManager.addSite("example.com", "user123", "pass123"); + siteManager.addSite("test.com", "testUser", "testPass"); + } } diff --git a/src/Tests/SteganographyImageTest.java b/src/Tests/SteganographyImageTest.java index 7f322b3..c0434b9 100644 --- a/src/Tests/SteganographyImageTest.java +++ b/src/Tests/SteganographyImageTest.java @@ -12,6 +12,7 @@ public class SteganographyImageTest { private static final String IMAGE_PATH = "src/Tests/assets/image.png"; private static final String IMAGE_PATH_SMALLEST_PNG = "src/Tests/assets/world_smallest.png"; + private static final String IMAGE_ENCODED_PATH = "src/Tests/assets/image_encoded.png"; @Test public void testEncodeDecode() throws IOException { @@ -22,6 +23,13 @@ public void testEncodeDecode() throws IOException { assertEquals(message, decodedMessage); } + @Test + public void testDecodeImage() { + Image image = new Image(IMAGE_ENCODED_PATH); + String message = image.decode(); + assertEquals("Hello", message); + } + @Test public void testEncodeMessageTooLarge() { Image image = new Image(IMAGE_PATH_SMALLEST_PNG); diff --git a/src/Tests/assets/test_databases.json b/src/Tests/assets/test_databases.json deleted file mode 100644 index ab6298e..0000000 --- a/src/Tests/assets/test_databases.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "duplicateDb": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8" -} \ No newline at end of file diff --git a/src/Tests/assets/test_sites.json b/src/Tests/assets/test_sites.json deleted file mode 100644 index 0f07589..0000000 --- a/src/Tests/assets/test_sites.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "sites": [] -} \ No newline at end of file