diff --git a/app/build.gradle b/app/build.gradle index 8d3a064..0505436 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,7 +14,6 @@ plugins { repositories { // Use Maven Central for resolving dependencies. mavenCentral() - jcenter() } dependencies { @@ -25,10 +24,8 @@ dependencies { implementation 'com.google.guava:guava:30.1-jre' // Use gson to serialize/deserialize json files implementation 'com.google.code.gson:gson:2.9.0' - // https://mvnrepository.com/artifact/org.mindrot/jbcrypt - implementation 'org.mindrot:jbcrypt:0.4' - + implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.4' } application { diff --git a/app/src/main/java/lightcontainer/App.java b/app/src/main/java/lightcontainer/App.java index e5909b5..3bb96f5 100644 --- a/app/src/main/java/lightcontainer/App.java +++ b/app/src/main/java/lightcontainer/App.java @@ -15,7 +15,6 @@ import lightcontainer.repository.StoreProcessorRepository; import lightcontainer.storage.AppData; import lightcontainer.storage.JsonAdapter; import lightcontainer.storage.Repository; -import org.mindrot.jbcrypt.BCrypt; import java.nio.file.Paths; diff --git a/app/src/main/java/lightcontainer/domains/client/Context.java b/app/src/main/java/lightcontainer/domains/client/Context.java index f577891..bd23773 100644 --- a/app/src/main/java/lightcontainer/domains/client/Context.java +++ b/app/src/main/java/lightcontainer/domains/client/Context.java @@ -4,6 +4,7 @@ import lightcontainer.storage.File; import lightcontainer.storage.ReadOnlyFile; import lightcontainer.storage.Repository; import lightcontainer.utils.AES_GCM; +import lightcontainer.utils.BCryptHasher; import lightcontainer.utils.ShaHasher; import java.util.List; @@ -44,12 +45,8 @@ public class Context { public boolean createUser(String login, String password) { try { String key = AES_GCM.generateSecretKey(); - - ShaHasher hasher = new ShaHasher(password); - password = hasher.nextHashing(); - String passwordSalt = hasher.getSalt(); - - if (this.repository.addUser(login, password, key, passwordSalt)) { + String hashedPassword = BCryptHasher.hashPassword(password); + if (this.repository.addUser(login, hashedPassword, key)) { this.login = login; return true; } @@ -69,23 +66,14 @@ public class Context { /** - * Permet de demander la connection de l'utilisateur + * Permet de demander la connexion de l'utilisateur * * @param login Login * @param password Mot de passe * @return TRUE si l'utilisateur a été authentifié */ public boolean signIn(String login, String password) { - String passwordSalt = this.repository.getUserPasswordSalt(login); - if (passwordSalt != null) { - ShaHasher hasher = new ShaHasher(password); - - if (this.repository.verifyUser(login, hasher.fromSalt(hasher.saltToByte(passwordSalt)))) { - this.login = login; - return true; - } - } - return false; + return this.repository.verifyUser(login, password); } /** diff --git a/app/src/main/java/lightcontainer/storage/AppData.java b/app/src/main/java/lightcontainer/storage/AppData.java index 153ea0e..29f22f0 100644 --- a/app/src/main/java/lightcontainer/storage/AppData.java +++ b/app/src/main/java/lightcontainer/storage/AppData.java @@ -80,8 +80,8 @@ public class AppData { * * @return True if the user was added. False if a user with the same name already exists. */ - public boolean addUser(String login, String password, String key, String passwordSalt) { - User user = new User(login, password, key, passwordSalt, new HashMap<>()); + public boolean addUser(String login, String password, String key) { + User user = new User(login, password, key, new HashMap<>()); if (this.users.containsKey(user.getName())) { return false; } else { @@ -143,11 +143,9 @@ public class AppData { * @param userName The name of the user who wants to retrieve the file. * @return The requested file matching file name and username, or null * if the user or file do not exist. - * + * @author Unknown... * @see User#getFile(String) * @see File - * - * @author Unknown... */ public File getFileOf(String fileName, String userName) { if (this.users.containsKey(userName)) { @@ -189,16 +187,16 @@ public class AppData { } } + /** + * @param login The login of the user to test password + * @param password The plain text password to try against user's hashed password + * @return True if password matches user's password. False if user could not be found or password didn't match + */ public boolean verifyUser(String login, String password) { User user = getUser(login); return user != null && user.verifyPassword(password); } - public String getUserPasswordSalt(String login) { - User user = getUser(login); - return user == null ? null : user.getPasswordSalt(); - } - /** * Méthode permettant de récupérer la clé AES d'un utilisateur * diff --git a/app/src/main/java/lightcontainer/storage/JsonAdapter.java b/app/src/main/java/lightcontainer/storage/JsonAdapter.java index c54722c..4913a4d 100644 --- a/app/src/main/java/lightcontainer/storage/JsonAdapter.java +++ b/app/src/main/java/lightcontainer/storage/JsonAdapter.java @@ -40,7 +40,6 @@ public class JsonAdapter implements Adapter { user.addProperty("name", current.getName()); user.addProperty("password", current.getPassword()); user.addProperty("aes_key", current.getAesKey()); - user.addProperty("passwordSalt", current.getPasswordSalt()); JsonArray files = new JsonArray(); Iterator fileIterator = current.fileIterator(); addFiles(fileIterator, files); @@ -109,11 +108,10 @@ public class JsonAdapter implements Adapter { String name = jsonUser.get("name").getAsString(); String password = jsonUser.get("password").getAsString(); String aeskey = jsonUser.get("aes_key").getAsString(); - String passwordSalt = jsonUser.get("passwordSalt").getAsString(); Map userFiles = new HashMap<>(); JsonArray jsonFiles = jsonUser.getAsJsonArray("files"); getFiles(userFiles, jsonFiles); - User user = new User(name, password, aeskey, passwordSalt, userFiles); + User user = new User(name, password, aeskey, userFiles); users.add(user); } } diff --git a/app/src/main/java/lightcontainer/storage/Repository.java b/app/src/main/java/lightcontainer/storage/Repository.java index 362fac4..a9a3b60 100644 --- a/app/src/main/java/lightcontainer/storage/Repository.java +++ b/app/src/main/java/lightcontainer/storage/Repository.java @@ -40,8 +40,8 @@ public class Repository { } } - public boolean addUser(String login, String password, String key, String passwordSalt) { - if (appData.addUser(login, password, key, passwordSalt)) { + public boolean addUser(String login, String password, String key) { + if (appData.addUser(login, password, key)) { save(); return true; } @@ -111,14 +111,15 @@ public class Repository { return appData.getAppConfig().getMulticastPort(); } + /** + * @param login The login of the user to test password + * @param password The plain text password to try against user's hashed password + * @return True if password matches user's password. False if user could not be found or password didn't match + */ public boolean verifyUser(String login, String password) { return appData.verifyUser(login, password); } - public String getUserPasswordSalt(String login) { - return appData.getUserPasswordSalt(login); - } - /** * Méthode permettant de récupérer le chemin de sauvegarde des fichiers * @@ -145,11 +146,9 @@ public class Repository { * @param userName The name of the user who wants to retrieve the file. * @return The requested file matching file name and username, or null * if the user or file do not exist. - * + * @author Unknown... * @see AppData#getFileOf(String, String) * @see File - * - * @author Unknown... */ public ReadOnlyFile getFileOf(String fileName, String userName) { return this.appData.getFileOf(fileName, userName); diff --git a/app/src/main/java/lightcontainer/storage/User.java b/app/src/main/java/lightcontainer/storage/User.java index 80d517b..896f76e 100644 --- a/app/src/main/java/lightcontainer/storage/User.java +++ b/app/src/main/java/lightcontainer/storage/User.java @@ -1,5 +1,7 @@ package lightcontainer.storage; +import lightcontainer.utils.BCryptHasher; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -17,15 +19,13 @@ public class User { private final String name; private final String password; private final String aesKey; - private final String passwordSalt; private final Map files; // Constructor - public User(String name, String password, String aesKey, String passwordSalt, Map files) { + public User(String name, String password, String aesKey, Map files) { this.name = name; this.password = password; this.aesKey = aesKey; - this.passwordSalt = passwordSalt; this.files = files; System.out.println(files.size() + " fichiers trouvéssss pour " + name); } @@ -42,10 +42,6 @@ public class User { return aesKey; } - public String getPasswordSalt() { - return this.passwordSalt; - } - public Iterator fileIterator() { return files.values().iterator(); } @@ -107,7 +103,11 @@ public class User { } } + /** + * @param password The plain text password to test + * @return True if password matches user's hashed password. False otherwise + */ public boolean verifyPassword(String password) { - return this.password.equals(password); + return BCryptHasher.checkPassword(password, this.password); } } diff --git a/app/src/main/java/lightcontainer/utils/BCryptHasher.java b/app/src/main/java/lightcontainer/utils/BCryptHasher.java new file mode 100644 index 0000000..91c633e --- /dev/null +++ b/app/src/main/java/lightcontainer/utils/BCryptHasher.java @@ -0,0 +1,15 @@ +package lightcontainer.utils; + +import org.mindrot.jbcrypt.BCrypt; + +public class BCryptHasher { + + + public static String hashPassword(String plainTextPassword) { + return BCrypt.hashpw(plainTextPassword, BCrypt.gensalt()); + } + + public static boolean checkPassword(String plainTextPassword, String hashedPassword) { + return BCrypt.checkpw(plainTextPassword, hashedPassword); + } +} diff --git a/app/src/main/resources/appdata.json b/app/src/main/resources/appdata.json index 7efd5d9..86e2736 100644 --- a/app/src/main/resources/appdata.json +++ b/app/src/main/resources/appdata.json @@ -1 +1,16 @@ -{"unicast_port":8000,"multicast_ip":"224.66.66.1","multicast_port":15502,"network_interface":"wlp1s0","tls":true,"storagePath":"/home/benjamin/ffe","users":[{"name":"aaaaa","password":"5d628c274ebb008324f1e199d3bfff0a3fe839730a7f2355e82850d7acca5e5ca64db9071abf3d91034295695f84a617","aes_key":"qlTH6TijnfMRnrS0Qf+k6IPKGp5LoRMXGxCq16e+mF4=","passwordSalt":"Ns8Al6DpqPsIDlCSRBVTEg==","files":[{"name":"ca.crt","fileNameSalt":"rTiE/FXNglnzbGBUGTDuJA==","size":4207,"iv":"0lg3QNhJ/eN292dbOvjShQ==","storage":["lightcontainerSB01"]},{"name":"main.py","fileNameSalt":"A3e6pNPkjZd4Rp2z9Nfzsg==","size":854,"iv":"rBqMLyPxtOQWJYasKFmrkA==","storage":["lightcontainerSB01"]},{"name":"README.md","fileNameSalt":"cDY6LMq13iqKknRS9OVBPw==","size":17,"iv":"jxc7hkIAoH64M8JF7FvNFw==","storage":["lightcontainerSB01"]}]}]} \ No newline at end of file +{ + "unicast_port": 8000, + "multicast_ip": "224.66.66.1", + "multicast_port": 15502, + "network_interface": "wlp1s0", + "tls": true, + "storagePath": "C:\\Users\\ledou\\Documents\\ffe", + "users": [ + { + "name": "aaaaa", + "password": "$2a$10$KQODXCTqCtZZCu86mkV30u3YKd1S5g9ZNaW04fExvn7zKY2Y0VuJS", + "aes_key": "k+mJzu9owT/Bz2MnNIDpWmYuPZasGTMlAQnBmlPl2cA=", + "files": [] + } + ] +} \ No newline at end of file