#685 Allow to configure number of rounds for PBKDF2
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.security.crypts.Pbkdf2;
|
||||
import fr.xephi.authme.security.crypts.Pbkdf2Django;
|
||||
|
||||
/**
|
||||
* Hash algorithms supported by AuthMe.
|
||||
@@ -19,8 +17,8 @@ public enum HashAlgorithm {
|
||||
MD5(fr.xephi.authme.security.crypts.MD5.class),
|
||||
MD5VB(fr.xephi.authme.security.crypts.MD5VB.class),
|
||||
MYBB(fr.xephi.authme.security.crypts.MYBB.class),
|
||||
PBKDF2(Pbkdf2.class),
|
||||
PBKDF2DJANGO(Pbkdf2Django.class),
|
||||
PBKDF2(fr.xephi.authme.security.crypts.Pbkdf2.class),
|
||||
PBKDF2DJANGO(fr.xephi.authme.security.crypts.Pbkdf2Django.class),
|
||||
PHPBB(fr.xephi.authme.security.crypts.PHPBB.class),
|
||||
PHPFUSION(fr.xephi.authme.security.crypts.PHPFUSION.class),
|
||||
@Deprecated
|
||||
|
||||
@@ -3,18 +3,30 @@ package fr.xephi.authme.security.crypts;
|
||||
import de.rtner.misc.BinTools;
|
||||
import de.rtner.security.auth.spi.PBKDF2Engine;
|
||||
import de.rtner.security.auth.spi.PBKDF2Parameters;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@Recommendation(Usage.RECOMMENDED)
|
||||
public class Pbkdf2 extends HexSaltedMethod {
|
||||
|
||||
private static final int NUMBER_OF_ITERATIONS = 10_000;
|
||||
private static final int DEFAULT_ROUNDS = 10_000;
|
||||
private int numberOfRounds;
|
||||
|
||||
@Inject
|
||||
Pbkdf2(Settings settings) {
|
||||
int configuredRounds = settings.getProperty(SecuritySettings.PBKDF2_NUMBER_OF_ROUNDS);
|
||||
this.numberOfRounds = configuredRounds > 0 ? configuredRounds : DEFAULT_ROUNDS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
String result = "pbkdf2_sha256$" + NUMBER_OF_ITERATIONS + "$" + salt + "$";
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), NUMBER_OF_ITERATIONS);
|
||||
String result = "pbkdf2_sha256$" + numberOfRounds + "$" + salt + "$";
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), numberOfRounds);
|
||||
PBKDF2Engine engine = new PBKDF2Engine(params);
|
||||
|
||||
return result + BinTools.bin2hex(engine.deriveKey(password, 64));
|
||||
@@ -26,9 +38,16 @@ public class Pbkdf2 extends HexSaltedMethod {
|
||||
if (line.length != 4) {
|
||||
return false;
|
||||
}
|
||||
int iterations;
|
||||
try {
|
||||
iterations = Integer.parseInt(line[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
ConsoleLogger.logException("Cannot read number of rounds for Pbkdf2", e);
|
||||
return false;
|
||||
}
|
||||
String salt = line[2];
|
||||
byte[] derivedKey = BinTools.hex2bin(line[3]);
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), 10000, derivedKey);
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "UTF-8", salt.getBytes(), iterations, derivedKey);
|
||||
PBKDF2Engine engine = new PBKDF2Engine(params);
|
||||
return engine.verifyKey(password);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import de.rtner.security.auth.spi.PBKDF2Engine;
|
||||
import de.rtner.security.auth.spi.PBKDF2Parameters;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.security.crypts.description.AsciiRestricted;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
|
||||
@@ -32,8 +31,7 @@ public class Pbkdf2Django extends HexSaltedMethod {
|
||||
try {
|
||||
iterations = Integer.parseInt(line[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
ConsoleLogger.warning("Could not read number of rounds for Pbkdf2Django:"
|
||||
+ StringUtils.formatException(e));
|
||||
ConsoleLogger.logException("Could not read number of rounds for Pbkdf2Django:", e);
|
||||
return false;
|
||||
}
|
||||
String salt = line[2];
|
||||
|
||||
@@ -86,6 +86,10 @@ public class SecuritySettings implements SettingsHolder {
|
||||
public static final Property<List<String>> LEGACY_HASHES =
|
||||
new EnumSetProperty<>(HashAlgorithm.class, "settings.security.legacyHashes");
|
||||
|
||||
@Comment("Number of rounds to use if passwordHash is set to PBKDF2. Default is 10000")
|
||||
public static final Property<Integer> PBKDF2_NUMBER_OF_ROUNDS =
|
||||
newProperty("settings.security.pbkdf2Rounds", 10000);
|
||||
|
||||
@Comment({"Prevent unsafe passwords from being used; put them in lowercase!",
|
||||
"You should always set 'help' as unsafePassword due to possible conflicts.",
|
||||
"unsafePasswords:",
|
||||
|
||||
Reference in New Issue
Block a user