mirror of
https://github.com/Quackster/Havana.git
synced 2025-07-02 20:57:47 +00:00
Move from Libsodium to native Java Argon2id hashing
This commit is contained in:
parent
621b201a3b
commit
2fbc3d6b2c
8 changed files with 50 additions and 35 deletions
|
@ -47,10 +47,14 @@ dependencies {
|
|||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.0'
|
||||
|
||||
// https://mvnrepository.com/artifact/org.springframework.security/spring-security-crypto
|
||||
implementation group: 'org.springframework.security', name: 'spring-security-crypto', version: '5.7.3'
|
||||
|
||||
// https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on
|
||||
implementation group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.70'
|
||||
|
||||
implementation 'com.maxmind.geoip2:geoip2:2.12.0'
|
||||
implementation 'com.github.bhlangonijr:chesslib:1.1.1'
|
||||
implementation 'com.goterl:lazysodium-java:5.0.1'
|
||||
implementation "net.java.dev.jna:jna:5.8.0"
|
||||
}
|
||||
|
||||
// Create fat jar with libraries inside of it.
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.alexdev.havana.util.config.writer.DefaultConfigWriter;
|
|||
import org.alexdev.havana.util.config.writer.GameConfigWriter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
|
@ -353,4 +354,14 @@ public class Havana {
|
|||
public static Gson getGson() {
|
||||
return gson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Argon2 password encoder instance.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Argon2PasswordEncoder getPasswordEncoder() {
|
||||
var encoder =new Argon2PasswordEncoder(16, 32, 1, 65536, 2);
|
||||
return encoder;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
package org.alexdev.havana.dao.mysql;
|
||||
|
||||
import com.goterl.lazysodium.LazySodiumJava;
|
||||
import com.goterl.lazysodium.SodiumJava;
|
||||
import com.goterl.lazysodium.interfaces.PwHash;
|
||||
import org.alexdev.havana.dao.Storage;
|
||||
import org.alexdev.havana.game.player.Player;
|
||||
import org.alexdev.havana.game.player.PlayerDetails;
|
||||
import org.alexdev.havana.game.player.PlayerManager;
|
||||
import org.alexdev.havana.util.DateUtil;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -15,7 +13,6 @@ import java.util.List;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class PlayerDao {
|
||||
public static final LazySodiumJava LIB_SODIUM = new LazySodiumJava(new SodiumJava());
|
||||
private static String figureBlacklist1 = "hd-180-1.hr-100-61.ch-210-66.lg-270-82.sh-290-80";
|
||||
|
||||
public static void resetOnline() {
|
||||
|
@ -353,13 +350,10 @@ public class PlayerDao {
|
|||
resultSet = preparedStatement.executeQuery();
|
||||
|
||||
if (resultSet.next()) {
|
||||
byte[] hashedPassword = (resultSet.getString("password") + '\0').getBytes(StandardCharsets.UTF_8);
|
||||
byte[] pass = password.getBytes(StandardCharsets.UTF_8);
|
||||
String databasePassword = resultSet.getString("password");
|
||||
|
||||
success = ((PwHash.Native) LIB_SODIUM).cryptoPwHashStrVerify(hashedPassword, pass, pass.length);
|
||||
|
||||
if (success) {
|
||||
fill(playerDetails, resultSet);
|
||||
if (PlayerManager.getInstance().passwordMatches(databasePassword, password)) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1010,23 +1004,4 @@ public class PlayerDao {
|
|||
row.getLong("totem_effect_expiry"), row.getLong("trade_ban_expiration"), row.getInt("favourite_group"),
|
||||
row.getString("created_at"));
|
||||
}
|
||||
|
||||
public static String createPassword(String password) throws Exception {
|
||||
byte[] pw = password.getBytes();
|
||||
byte[] outputHash = new byte[PwHash.STR_BYTES];
|
||||
PwHash.Native pwHash = (PwHash.Native) PlayerDao.LIB_SODIUM;
|
||||
boolean success = pwHash.cryptoPwHashStr(
|
||||
outputHash,
|
||||
pw,
|
||||
pw.length,
|
||||
PwHash.OPSLIMIT_INTERACTIVE,
|
||||
PwHash.MEMLIMIT_INTERACTIVE
|
||||
);
|
||||
|
||||
if (!success) {
|
||||
throw new Exception("Password creation was a failure!");
|
||||
}
|
||||
|
||||
return new String(outputHash).replace((char)0 + "", "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import org.alexdev.havana.game.entity.Entity;
|
|||
import org.alexdev.havana.game.entity.EntityType;
|
||||
import org.alexdev.havana.game.player.Player;
|
||||
import org.alexdev.havana.game.player.PlayerDetails;
|
||||
import org.alexdev.havana.game.player.PlayerManager;
|
||||
import org.alexdev.havana.game.player.PlayerRank;
|
||||
import org.alexdev.havana.messages.outgoing.alerts.ALERT;
|
||||
|
||||
|
@ -40,7 +41,7 @@ public class RecoverAccountCommand extends Command {
|
|||
}
|
||||
|
||||
player.send(new ALERT(targetUser.getName() + "'s password has been reset to: changeme123"));
|
||||
PlayerDao.setPassword(targetUser.getId(), PlayerDao.createPassword("changeme123"));
|
||||
PlayerDao.setPassword(targetUser.getId(), PlayerManager.getInstance().createPassword("changeme123"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.alexdev.havana.game.player;
|
||||
|
||||
import org.alexdev.havana.Havana;
|
||||
import org.alexdev.havana.dao.mysql.PlayerDao;
|
||||
import org.alexdev.havana.game.GameScheduler;
|
||||
import org.alexdev.havana.game.player.statistics.PlayerStatistic;
|
||||
|
@ -283,6 +284,26 @@ public class PlayerManager {
|
|||
return activePlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create password hash
|
||||
*
|
||||
* @param password password to hash
|
||||
* @return hashed password
|
||||
* @throws Exception
|
||||
*/
|
||||
public String createPassword(String password) {
|
||||
return Havana.getPasswordEncoder().encode(password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the hash matches the entered password.
|
||||
*
|
||||
* @return true, if success
|
||||
*/
|
||||
public boolean passwordMatches(String databasePassword, String enteredPassword) {
|
||||
return Havana.getPasswordEncoder().matches(enteredPassword, databasePassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get daily player peak
|
||||
*
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.alexdev.havana.dao.mysql.PlayerStatisticsDao;
|
|||
import org.alexdev.havana.dao.mysql.WardrobeDao;
|
||||
import org.alexdev.havana.game.misc.figure.FigureManager;
|
||||
import org.alexdev.havana.game.player.PlayerDetails;
|
||||
import org.alexdev.havana.game.player.PlayerManager;
|
||||
import org.alexdev.havana.game.player.Wardrobe;
|
||||
import org.alexdev.havana.game.player.statistics.PlayerStatistic;
|
||||
import org.alexdev.havana.game.player.statistics.PlayerStatisticManager;
|
||||
|
@ -229,7 +230,7 @@ public class ProfileController {
|
|||
webConnection.session().set("alertMessage", "Your password has been changed successfully. You will need to login again.");
|
||||
webConnection.session().set("alertColour", "green");
|
||||
|
||||
PlayerDao.setPassword(playerDetails.getId(), PlayerDao.createPassword(newPassword));
|
||||
PlayerDao.setPassword(playerDetails.getId(), PlayerManager.getInstance().createPassword(newPassword));
|
||||
logout = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.alexdev.duckhttpd.server.connection.WebConnection;
|
|||
import org.alexdev.havana.dao.mysql.PlayerDao;
|
||||
import org.alexdev.havana.dao.mysql.PlayerStatisticsDao;
|
||||
import org.alexdev.havana.game.player.PlayerDetails;
|
||||
import org.alexdev.havana.game.player.PlayerManager;
|
||||
import org.alexdev.havana.game.player.statistics.PlayerStatistic;
|
||||
import org.alexdev.havana.util.DateUtil;
|
||||
import org.alexdev.havana.util.config.GameConfiguration;
|
||||
|
@ -137,7 +138,7 @@ public class RecoveryController {
|
|||
webConnection.session().set("alertMessage", "Your password has been changed successfully.");
|
||||
webConnection.session().set("alertColour", "green");
|
||||
|
||||
PlayerDao.setPassword(userId, PlayerDao.createPassword(newPassword));
|
||||
PlayerDao.setPassword(userId, PlayerManager.getInstance().createPassword(newPassword));
|
||||
EmailDao.removeRecoveryCode(userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.alexdev.havana.dao.mysql.PlayerDao;
|
|||
import org.alexdev.havana.dao.mysql.PlayerStatisticsDao;
|
||||
import org.alexdev.havana.dao.mysql.ReferredDao;
|
||||
import org.alexdev.havana.game.misc.figure.FigureManager;
|
||||
import org.alexdev.havana.game.player.PlayerManager;
|
||||
import org.alexdev.havana.util.DateUtil;
|
||||
import org.alexdev.havana.util.FigureUtil;
|
||||
import org.alexdev.havana.util.config.GameConfiguration;
|
||||
|
@ -158,7 +159,7 @@ public class RegisterController {
|
|||
return;
|
||||
}
|
||||
|
||||
String hashedPassword = PlayerDao.createPassword(webConnection.session().getString("registerPassword"));
|
||||
String hashedPassword = PlayerManager.getInstance().createPassword(webConnection.session().getString("registerPassword"));
|
||||
int userId = RegisterDao.newUser(
|
||||
webConnection.session().getString("registerUsername"),
|
||||
hashedPassword,
|
||||
|
|
Loading…
Add table
Reference in a new issue