BCrypt implémenté (voir dépendance jBCrypt)
This commit is contained in:
parent
986e06b073
commit
52ee6194b9
@ -14,7 +14,6 @@ plugins {
|
|||||||
repositories {
|
repositories {
|
||||||
// Use Maven Central for resolving dependencies.
|
// Use Maven Central for resolving dependencies.
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -25,10 +24,8 @@ dependencies {
|
|||||||
implementation 'com.google.guava:guava:30.1-jre'
|
implementation 'com.google.guava:guava:30.1-jre'
|
||||||
// Use gson to serialize/deserialize json files
|
// Use gson to serialize/deserialize json files
|
||||||
implementation 'com.google.code.gson:gson:2.9.0'
|
implementation 'com.google.code.gson:gson:2.9.0'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.mindrot/jbcrypt
|
// https://mvnrepository.com/artifact/org.mindrot/jbcrypt
|
||||||
implementation 'org.mindrot:jbcrypt:0.4'
|
implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.4'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
|
@ -15,7 +15,6 @@ import lightcontainer.repository.StoreProcessorRepository;
|
|||||||
import lightcontainer.storage.AppData;
|
import lightcontainer.storage.AppData;
|
||||||
import lightcontainer.storage.JsonAdapter;
|
import lightcontainer.storage.JsonAdapter;
|
||||||
import lightcontainer.storage.Repository;
|
import lightcontainer.storage.Repository;
|
||||||
import org.mindrot.jbcrypt.BCrypt;
|
|
||||||
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import lightcontainer.storage.File;
|
|||||||
import lightcontainer.storage.ReadOnlyFile;
|
import lightcontainer.storage.ReadOnlyFile;
|
||||||
import lightcontainer.storage.Repository;
|
import lightcontainer.storage.Repository;
|
||||||
import lightcontainer.utils.AES_GCM;
|
import lightcontainer.utils.AES_GCM;
|
||||||
|
import lightcontainer.utils.BCryptHasher;
|
||||||
import lightcontainer.utils.ShaHasher;
|
import lightcontainer.utils.ShaHasher;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -44,12 +45,8 @@ public class Context {
|
|||||||
public boolean createUser(String login, String password) {
|
public boolean createUser(String login, String password) {
|
||||||
try {
|
try {
|
||||||
String key = AES_GCM.generateSecretKey();
|
String key = AES_GCM.generateSecretKey();
|
||||||
|
String hashedPassword = BCryptHasher.hashPassword(password);
|
||||||
ShaHasher hasher = new ShaHasher(password);
|
if (this.repository.addUser(login, hashedPassword, key)) {
|
||||||
password = hasher.nextHashing();
|
|
||||||
String passwordSalt = hasher.getSalt();
|
|
||||||
|
|
||||||
if (this.repository.addUser(login, password, key, passwordSalt)) {
|
|
||||||
this.login = login;
|
this.login = login;
|
||||||
return true;
|
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 login Login
|
||||||
* @param password Mot de passe
|
* @param password Mot de passe
|
||||||
* @return TRUE si l'utilisateur a été authentifié
|
* @return TRUE si l'utilisateur a été authentifié
|
||||||
*/
|
*/
|
||||||
public boolean signIn(String login, String password) {
|
public boolean signIn(String login, String password) {
|
||||||
String passwordSalt = this.repository.getUserPasswordSalt(login);
|
return this.repository.verifyUser(login, password);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,8 +80,8 @@ public class AppData {
|
|||||||
*
|
*
|
||||||
* @return True if the user was added. False if a user with the same name already exists.
|
* @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) {
|
public boolean addUser(String login, String password, String key) {
|
||||||
User user = new User(login, password, key, passwordSalt, new HashMap<>());
|
User user = new User(login, password, key, new HashMap<>());
|
||||||
if (this.users.containsKey(user.getName())) {
|
if (this.users.containsKey(user.getName())) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -143,11 +143,9 @@ public class AppData {
|
|||||||
* @param userName The name of the user who wants to retrieve the file.
|
* @param userName The name of the user who wants to retrieve the file.
|
||||||
* @return The requested file matching file name and username, or null
|
* @return The requested file matching file name and username, or null
|
||||||
* if the user or file do not exist.
|
* if the user or file do not exist.
|
||||||
*
|
* @author Unknown...
|
||||||
* @see User#getFile(String)
|
* @see User#getFile(String)
|
||||||
* @see File
|
* @see File
|
||||||
*
|
|
||||||
* @author Unknown...
|
|
||||||
*/
|
*/
|
||||||
public File getFileOf(String fileName, String userName) {
|
public File getFileOf(String fileName, String userName) {
|
||||||
if (this.users.containsKey(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) {
|
public boolean verifyUser(String login, String password) {
|
||||||
User user = getUser(login);
|
User user = getUser(login);
|
||||||
return user != null && user.verifyPassword(password);
|
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
|
* Méthode permettant de récupérer la clé AES d'un utilisateur
|
||||||
*
|
*
|
||||||
|
@ -40,7 +40,6 @@ public class JsonAdapter implements Adapter {
|
|||||||
user.addProperty("name", current.getName());
|
user.addProperty("name", current.getName());
|
||||||
user.addProperty("password", current.getPassword());
|
user.addProperty("password", current.getPassword());
|
||||||
user.addProperty("aes_key", current.getAesKey());
|
user.addProperty("aes_key", current.getAesKey());
|
||||||
user.addProperty("passwordSalt", current.getPasswordSalt());
|
|
||||||
JsonArray files = new JsonArray();
|
JsonArray files = new JsonArray();
|
||||||
Iterator<File> fileIterator = current.fileIterator();
|
Iterator<File> fileIterator = current.fileIterator();
|
||||||
addFiles(fileIterator, files);
|
addFiles(fileIterator, files);
|
||||||
@ -109,11 +108,10 @@ public class JsonAdapter implements Adapter {
|
|||||||
String name = jsonUser.get("name").getAsString();
|
String name = jsonUser.get("name").getAsString();
|
||||||
String password = jsonUser.get("password").getAsString();
|
String password = jsonUser.get("password").getAsString();
|
||||||
String aeskey = jsonUser.get("aes_key").getAsString();
|
String aeskey = jsonUser.get("aes_key").getAsString();
|
||||||
String passwordSalt = jsonUser.get("passwordSalt").getAsString();
|
|
||||||
Map<String, File> userFiles = new HashMap<>();
|
Map<String, File> userFiles = new HashMap<>();
|
||||||
JsonArray jsonFiles = jsonUser.getAsJsonArray("files");
|
JsonArray jsonFiles = jsonUser.getAsJsonArray("files");
|
||||||
getFiles(userFiles, jsonFiles);
|
getFiles(userFiles, jsonFiles);
|
||||||
User user = new User(name, password, aeskey, passwordSalt, userFiles);
|
User user = new User(name, password, aeskey, userFiles);
|
||||||
users.add(user);
|
users.add(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,8 @@ public class Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addUser(String login, String password, String key, String passwordSalt) {
|
public boolean addUser(String login, String password, String key) {
|
||||||
if (appData.addUser(login, password, key, passwordSalt)) {
|
if (appData.addUser(login, password, key)) {
|
||||||
save();
|
save();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -111,14 +111,15 @@ public class Repository {
|
|||||||
return appData.getAppConfig().getMulticastPort();
|
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) {
|
public boolean verifyUser(String login, String password) {
|
||||||
return appData.verifyUser(login, 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
|
* 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.
|
* @param userName The name of the user who wants to retrieve the file.
|
||||||
* @return The requested file matching file name and username, or null
|
* @return The requested file matching file name and username, or null
|
||||||
* if the user or file do not exist.
|
* if the user or file do not exist.
|
||||||
*
|
* @author Unknown...
|
||||||
* @see AppData#getFileOf(String, String)
|
* @see AppData#getFileOf(String, String)
|
||||||
* @see File
|
* @see File
|
||||||
*
|
|
||||||
* @author Unknown...
|
|
||||||
*/
|
*/
|
||||||
public ReadOnlyFile getFileOf(String fileName, String userName) {
|
public ReadOnlyFile getFileOf(String fileName, String userName) {
|
||||||
return this.appData.getFileOf(fileName, userName);
|
return this.appData.getFileOf(fileName, userName);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package lightcontainer.storage;
|
package lightcontainer.storage;
|
||||||
|
|
||||||
|
import lightcontainer.utils.BCryptHasher;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,15 +19,13 @@ public class User {
|
|||||||
private final String name;
|
private final String name;
|
||||||
private final String password;
|
private final String password;
|
||||||
private final String aesKey;
|
private final String aesKey;
|
||||||
private final String passwordSalt;
|
|
||||||
private final Map<String, File> files;
|
private final Map<String, File> files;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public User(String name, String password, String aesKey, String passwordSalt, Map<String, File> files) {
|
public User(String name, String password, String aesKey, Map<String, File> files) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.aesKey = aesKey;
|
this.aesKey = aesKey;
|
||||||
this.passwordSalt = passwordSalt;
|
|
||||||
this.files = files;
|
this.files = files;
|
||||||
System.out.println(files.size() + " fichiers trouvéssss pour " + name);
|
System.out.println(files.size() + " fichiers trouvéssss pour " + name);
|
||||||
}
|
}
|
||||||
@ -42,10 +42,6 @@ public class User {
|
|||||||
return aesKey;
|
return aesKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPasswordSalt() {
|
|
||||||
return this.passwordSalt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<File> fileIterator() {
|
public Iterator<File> fileIterator() {
|
||||||
return files.values().iterator();
|
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) {
|
public boolean verifyPassword(String password) {
|
||||||
return this.password.equals(password);
|
return BCryptHasher.checkPassword(password, this.password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
app/src/main/java/lightcontainer/utils/BCryptHasher.java
Normal file
15
app/src/main/java/lightcontainer/utils/BCryptHasher.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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"]}]}]}
|
{
|
||||||
|
"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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user