diff --git a/.gitignore b/.gitignore index 70e39ba..1e3cefb 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ log.txt secureData*.txt logfile.txt rmc_log.txt +logfileConf.txt diff --git a/JFramework/auth/src/main/java/it/richkmeli/jframework/auth/AuthDatabaseJframeworkManager.java b/JFramework/auth/src/main/java/it/richkmeli/jframework/auth/AuthDatabaseJframeworkManager.java index 69b74cc..8e846e9 100644 --- a/JFramework/auth/src/main/java/it/richkmeli/jframework/auth/AuthDatabaseJframeworkManager.java +++ b/JFramework/auth/src/main/java/it/richkmeli/jframework/auth/AuthDatabaseJframeworkManager.java @@ -54,7 +54,7 @@ public User getUser(String email) throws AuthDatabaseException, ModelException { public boolean addUser(User user) throws AuthDatabaseException { //Logger.info("AuthDatabaseManager, addUser. User: " + user.email); //String hash = Crypto.hash(user.getPassword()); - String password = Crypto.hashPassword(user.getPassword(), false); + String password = Crypto.hashPassword(user.getPassword()); user.setPassword(password); try { return create(user); @@ -81,7 +81,7 @@ public boolean isUserPresent(String email) throws AuthDatabaseException, ModelEx @Override public boolean editPassword(String email, String pass) throws AuthDatabaseException, ModelException { - String password = Crypto.hashPassword(pass, false); + String password = Crypto.hashPassword(pass); try { return update(new User(email, password, null)); } catch (DatabaseException e) { diff --git a/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/Crypto.java b/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/Crypto.java index 6990a2f..8b12c94 100644 --- a/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/Crypto.java +++ b/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/Crypto.java @@ -195,15 +195,27 @@ public static String hash(String input) { return SHA256.hash(input); } - // salt is enabled only during login process, instead set it as false for saving - // passwords into DB - public static String hashPassword(String password, boolean saltEnabled) { - return PasswordManager.hashPassword(password, saltEnabled); + /** + * Hashes a password using a randomly generated salt. + * This method is a wrapper for {@link PasswordManager#hashPassword(String)}. + * + * @param password the password to hash + * @return the hashed password with the salt, Base64 encoded + */ + public static String hashPassword(String password) { + return PasswordManager.hashPassword(password); } - // hashedPassword = db password, hashedSaltPassword = login password - public static boolean verifyPassword(String hashedPassword, String hashedSaltPassword) { - return PasswordManager.verifyPassword(hashedPassword, hashedSaltPassword); + /** + * Verifies a plaintext password against a stored hashed password. + * This method is a wrapper for {@link PasswordManager#verifyPassword(String, String)}. + * + * @param plaintextPassword the password to verify + * @param hashedPassword the stored hashed password (must contain the salt) + * @return true if the password is correct, false otherwise + */ + public static boolean verifyPassword(String plaintextPassword, String hashedPassword) { + return PasswordManager.verifyPassword(plaintextPassword, hashedPassword); } public static void putData(File file, String secretKey, String key, String value) { diff --git a/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/controller/PasswordManager.java b/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/controller/PasswordManager.java index 7d2b934..085ff63 100644 --- a/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/controller/PasswordManager.java +++ b/JFramework/crypto/src/main/java/it/richkmeli/jframework/crypto/controller/PasswordManager.java @@ -8,38 +8,38 @@ public class PasswordManager { - // salt is enabled only during login process, instead set it as false for saving passwords into DB - public static String hashPassword(String password, boolean saltEnabled) { - // salt generation - /*Random r = new SecureRandom(); - byte[] salt = new byte[9]; - r.nextBytes(salt);*/ - String saltS = ""; - String hashedPassword = ""; - if (saltEnabled) { - saltS = RandomStringGenerator.generateAlphanumericString(9);//new String(salt); - hashedPassword = SHA256.hash(SHA256.hash(password) + saltS); - } else { - saltS = "000000000"; - hashedPassword = SHA256.hash(password); - } - - //System.out.println("hashPassword, saltS: " + saltS + " " + saltS.length() + " | hashedPassword: " + hashedPassword + " " + hashedPassword.length()); - String out = saltS + hashedPassword; + /** + * Hashes a password using a randomly generated salt. + * The salt is prepended to the hash and the result is Base64 encoded. + * + * @param password the password to hash + * @return the hashed password with the salt, Base64 encoded + */ + public static String hashPassword(String password) { + String salt = RandomStringGenerator.generateAlphanumericString(16); + String hashedPassword = SHA256.hash(password + salt); + String out = salt + hashedPassword; return Base64.getUrlEncoder().encodeToString(out.getBytes(Charset.defaultCharset())); } - // hashedPassword = db password, hashedSaltPassword = login password - public static boolean verifyPassword(String hashedPassword, String hashedSaltPassword) { - String decodedHashedPassword = new String(Base64.getUrlDecoder().decode(hashedPassword)); - String decodedHashedSaltPassword = new String(Base64.getUrlDecoder().decode(hashedSaltPassword)); - String salt = decodedHashedSaltPassword.substring(0, 9); - String hashSP = decodedHashedSaltPassword.substring(9); - String hashP = decodedHashedPassword.substring(9); - - //System.out.println("verifyPassword, saltS: " + salt + " " + salt.length() + " | hashedSaltPassword: " + hashSP + " " + hashSP.length()); - String hp = SHA256.hash(hashP + salt); - - return hashSP.equalsIgnoreCase(hp); + /** + * Verifies a plaintext password against a stored hashed password. + * + * @param plaintextPassword the password to verify + * @param hashedPassword the stored hashed password (must contain the salt) + * @return true if the password is correct, false otherwise + */ + public static boolean verifyPassword(String plaintextPassword, String hashedPassword) { + try { + String decodedHashedPassword = new String(Base64.getUrlDecoder().decode(hashedPassword)); + // The salt is the first 16 characters of the decoded hash + String salt = decodedHashedPassword.substring(0, 16); + String storedHash = decodedHashedPassword.substring(16); + String computedHash = SHA256.hash(plaintextPassword + salt); + return storedHash.equals(computedHash); + } catch (Exception e) { + // If any error occurs (e.g., decoding, substring), verification fails + return false; + } } } diff --git a/JFramework/crypto/src/test/java/crypto/CryptoTest.java b/JFramework/crypto/src/test/java/crypto/CryptoTest.java index 9c7420b..918a2d8 100644 --- a/JFramework/crypto/src/test/java/crypto/CryptoTest.java +++ b/JFramework/crypto/src/test/java/crypto/CryptoTest.java @@ -236,14 +236,12 @@ private void payloadExchange(File secureDataClient, File secureDataServer, Strin @Test public void passwordTest() { - for (String s : cryptoStrings) { - // password for DB - String dbPW = Crypto.hashPassword(s, false); - - // password for login - String loginPW = Crypto.hashPassword(s, true); + for (String password : cryptoStrings) { + // Hash the password (which now always includes a salt) + String hashedPassword = Crypto.hashPassword(password); - assertTrue(Crypto.verifyPassword(dbPW, loginPW)); + // Verify the original password against the new hash + assertTrue(Crypto.verifyPassword(password, hashedPassword)); } } diff --git a/JFramework/orm/src/test/java/orm/DatabaseManagerTest.java b/JFramework/orm/src/test/java/orm/DatabaseManagerTest.java index 429ee99..a61cc10 100644 --- a/JFramework/orm/src/test/java/orm/DatabaseManagerTest.java +++ b/JFramework/orm/src/test/java/orm/DatabaseManagerTest.java @@ -63,22 +63,22 @@ private void createAuthdb() throws DatabaseException { password, false); authDatabaseManager.addUser(u); - assertTrue(authDatabaseManager.checkPassword(email, Crypto.hashPassword(password, true))); + assertTrue(authDatabaseManager.checkPassword(email, password)); assertFalse(authDatabaseManager.isAdmin(email)); } - assertTrue(authDatabaseManager.checkPassword("richk@i.it", Crypto.hashPassword("00000000", true))); + assertTrue(authDatabaseManager.checkPassword("richk@i.it", "00000000")); } private void createDevicedb() throws DatabaseException { String email = "richk@i.it"; - authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000"), false)); deviceDatabaseManager.addDevice(new Device("device1", "192.168.0.100", "9000", "20-10-2018", "testencryptionkey", email, "start##start##start", "")); for (int i = 0; i < ENTRIES; i++) { String device = "device" + RandomStringGenerator.generateAlphanumericString(8) + "_" + i; email = RandomStringGenerator.generateAlphanumericString(8) + "@" + RandomStringGenerator.generateAlphanumericString(8) + "." + RandomStringGenerator.generateAlphanumericString(2); - authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000"), false)); String encryptionKey = RandomStringGenerator.generateAlphanumericString(32); String commands = RandomStringGenerator.generateAlphanumericString(50); String commandsOutput = RandomStringGenerator.generateAlphanumericString(100); @@ -95,13 +95,13 @@ private void createDevicedb() throws DatabaseException { private void createRMCdb() throws DatabaseException { String email = "richk@i.it"; - authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000"), false)); rmcDatabaseManager.addRMC(new RMC(email, "ClientID_1")); for (int i = 0; i < ENTRIES; i++) { email = RandomStringGenerator.generateAlphanumericString(8) + "@" + RandomStringGenerator.generateAlphanumericString(8) + "." + RandomStringGenerator.generateAlphanumericString(2); String clientID = RandomStringGenerator.generateAlphanumericString(32); - authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000"), false)); rmcDatabaseManager.addRMC(new RMC(email, clientID)); assertFalse(rmcDatabaseManager.getAllRMCs().isEmpty()); @@ -136,7 +136,7 @@ private void readAuthdb() throws DatabaseException { private void readDevicedb() throws DatabaseException { // test read String device = "deviceread"; - authDatabaseManager.addUser(new UserTest("richk@i.it", PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest("richk@i.it", PasswordManager.hashPassword("00000000"), false)); deviceDatabaseManager.addDevice(new Device(device, "192.168.0.100", "9000", "20-10-2018", "testencryptionkey", "richk@i.it", "start##start##start", "")); @@ -150,7 +150,7 @@ private void readRMCdb() throws DatabaseException { // test read String email = "richk@i.it"; String clientID = "clientIDread"; - authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000", false), false)); + authDatabaseManager.addUser(new UserTest(email, PasswordManager.hashPassword("00000000"), false)); rmcDatabaseManager.addRMC(new RMC(email, clientID)); assertNotNull(rmcDatabaseManager.getRMCs(email)); @@ -262,11 +262,11 @@ private void updateAuthdb() throws DatabaseException { "testencryptionkey", "richk@i.it", "start##start##start", "")); authDatabaseManager.addUser(new UserTest(email, "00000000", true)); - assertTrue(authDatabaseManager.checkPassword(email, PasswordManager.hashPassword("00000000", true))); + assertTrue(authDatabaseManager.checkPassword(email, "00000000")); assertTrue(authDatabaseManager.isAdmin(email)); authDatabaseManager.editPassword(email, "00000001"); - assertTrue(authDatabaseManager.checkPassword(email, PasswordManager.hashPassword("00000001", true))); + assertTrue(authDatabaseManager.checkPassword(email, "00000001")); authDatabaseManager.editAdmin(email, false); assertFalse(authDatabaseManager.isAdmin(email)); diff --git a/JFramework/orm/src/test/java/orm/dataexample/auth/AuthDatabaseManagerTest.java b/JFramework/orm/src/test/java/orm/dataexample/auth/AuthDatabaseManagerTest.java index 87c1f8f..7e3bd2c 100644 --- a/JFramework/orm/src/test/java/orm/dataexample/auth/AuthDatabaseManagerTest.java +++ b/JFramework/orm/src/test/java/orm/dataexample/auth/AuthDatabaseManagerTest.java @@ -38,7 +38,7 @@ public UserTest getUser(String email) throws DatabaseException { public boolean addUser(UserTest user) throws DatabaseException { //Logger.info("AuthDatabaseManager, addUser. User: " + user.email); //String hash = Crypto.hash(user.getPassword()); - String password = Crypto.hashPassword(user.getPassword(), false); + String password = Crypto.hashPassword(user.getPassword()); user.setPassword(password); return create(user); } @@ -53,7 +53,7 @@ public boolean isUserPresent(String email) throws DatabaseException { } public boolean editPassword(String email, String pass) throws DatabaseException { - String password = Crypto.hashPassword(pass, false); + String password = Crypto.hashPassword(pass); return update(new UserTest(email, password, null)); } @@ -61,10 +61,10 @@ public boolean editAdmin(String email, Boolean isAdmin) throws DatabaseException return update(new UserTest(email, null, isAdmin)); } - public boolean checkPassword(String email, String pass) throws DatabaseException { + public boolean checkPassword(String email, String plaintextPassword) throws DatabaseException { UserTest user = getUser(email); if (user != null) { - return Crypto.verifyPassword(user.getPassword(), pass); + return Crypto.verifyPassword(plaintextPassword, user.getPassword()); } else { return false; }