#1016 Deprecate MD5, SHA1, SHA512: no longer allowed for active use

- Deprecate unsalted hashes: if such a hash is configured, move it to the legacy hashes setting to still support the existing hashes in the database but hash all passwords from now on with our default, SHA256.
This commit is contained in:
ljacqu
2017-10-19 21:30:19 +02:00
parent 7d445217d6
commit fca77b940f
14 changed files with 121 additions and 87 deletions
@@ -23,7 +23,6 @@ import fr.xephi.authme.listener.PlayerListener18;
import fr.xephi.authme.listener.PlayerListener19;
import fr.xephi.authme.listener.PlayerListener19Spigot;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.Sha256;
import fr.xephi.authme.service.BackupService;
import fr.xephi.authme.service.BukkitService;
@@ -268,13 +267,6 @@ public class AuthMe extends JavaPlugin {
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
}
// Unsalted hashes will be deprecated in 5.4 (see Github issue #1016)
HashAlgorithm hash = settings.getProperty(SecuritySettings.PASSWORD_HASH);
if (OnStartupTasks.isHashDeprecatedIn54(hash)) {
ConsoleLogger.warning("You are using an unsalted hash (" + hash + "). Support for this will be removed "
+ "in 5.4 -- do you still need it? Comment on https://github.com/AuthMe/AuthMeReloaded/issues/1016");
}
}
/**
@@ -7,9 +7,6 @@ import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
@@ -103,23 +100,4 @@ public class OnStartupTasks {
}
}, 1, TICKS_PER_MINUTE * settings.getProperty(EmailSettings.DELAY_RECALL));
}
/**
* Returns whether the hash algorithm is deprecated and won't be able
* to be actively used anymore in 5.4.
*
* @param hash the hash algorithm to check
* @return true if the hash will be deprecated, false otherwise
* @see <a href="https://github.com/AuthMe/AuthMeReloaded/issues/1016">#1016</a>
*/
public static boolean isHashDeprecatedIn54(HashAlgorithm hash) {
if (hash.getClazz() == null || hash == HashAlgorithm.PLAINTEXT) {
// Exclude PLAINTEXT from this check because it already has a mandatory migration, which takes care of
// sending all the necessary messages and warnings.
return false;
}
Recommendation recommendation = hash.getClazz().getAnnotation(Recommendation.class);
return recommendation != null && recommendation.value() == Usage.DEPRECATED;
}
}
@@ -10,34 +10,34 @@ public enum HashAlgorithm {
BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class),
BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class),
CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class),
DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
IPB3(fr.xephi.authme.security.crypts.Ipb3.class),
IPB4(fr.xephi.authme.security.crypts.Ipb4.class),
JOOMLA(fr.xephi.authme.security.crypts.Joomla.class),
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(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
PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class),
ROYALAUTH(fr.xephi.authme.security.crypts.RoyalAuth.class),
SALTED2MD5(fr.xephi.authme.security.crypts.Salted2Md5.class),
SALTEDSHA512(fr.xephi.authme.security.crypts.SaltedSha512.class),
SHA1(fr.xephi.authme.security.crypts.Sha1.class),
SHA256(fr.xephi.authme.security.crypts.Sha256.class),
SHA512(fr.xephi.authme.security.crypts.Sha512.class),
SMF(fr.xephi.authme.security.crypts.Smf.class),
TWO_FACTOR(fr.xephi.authme.security.crypts.TwoFactor.class),
WBB3(fr.xephi.authme.security.crypts.Wbb3.class),
WBB4(fr.xephi.authme.security.crypts.Wbb4.class),
WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class),
WORDPRESS(fr.xephi.authme.security.crypts.Wordpress.class),
XAUTH(fr.xephi.authme.security.crypts.XAuth.class),
XFBCRYPT(fr.xephi.authme.security.crypts.XfBCrypt.class),
CUSTOM(null);
CUSTOM(null),
@Deprecated DOUBLEMD5(fr.xephi.authme.security.crypts.DoubleMd5.class),
@Deprecated MD5(fr.xephi.authme.security.crypts.Md5.class),
@Deprecated PLAINTEXT(fr.xephi.authme.security.crypts.PlainText.class),
@Deprecated SHA1(fr.xephi.authme.security.crypts.Sha1.class),
@Deprecated SHA512(fr.xephi.authme.security.crypts.Sha512.class),
@Deprecated WHIRLPOOL(fr.xephi.authme.security.crypts.Whirlpool.class);
private final Class<? extends EncryptionMethod> clazz;
@@ -5,6 +5,7 @@ import fr.xephi.authme.security.crypts.description.Usage;
import static fr.xephi.authme.security.HashUtils.md5;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class DoubleMd5 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Md5 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Sha1 extends UnsaltedMethod {
@@ -4,6 +4,7 @@ import fr.xephi.authme.security.HashUtils;
import fr.xephi.authme.security.crypts.description.Recommendation;
import fr.xephi.authme.security.crypts.description.Usage;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Sha512 extends UnsaltedMethod {
@@ -64,6 +64,7 @@ import fr.xephi.authme.security.crypts.description.Usage;
import java.util.Arrays;
@Deprecated
@Recommendation(Usage.DEPRECATED)
public class Whirlpool extends UnsaltedMethod {
@@ -3,8 +3,8 @@ package fr.xephi.authme.settings;
import ch.jalu.configme.properties.Property;
import ch.jalu.configme.resource.PropertyResource;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -27,9 +27,9 @@ public class EnumSetProperty<E extends Enum<E>> extends Property<Set<E>> {
@Override
protected Set<E> getFromResource(PropertyResource resource) {
List<?> elements = resource.getList(getPath());
if (elements != null) {
return elements.stream()
Object entry = resource.getObject(getPath());
if (entry instanceof Collection<?>) {
return ((Collection<?>) entry).stream()
.map(val -> toEnum(String.valueOf(val)))
.filter(e -> e != null)
.collect(Collectors.toCollection(LinkedHashSet::new));
@@ -10,6 +10,8 @@ import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.process.register.RegisterSecondaryArgument;
import fr.xephi.authme.process.register.RegistrationType;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.security.crypts.EncryptionMethod;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
@@ -20,6 +22,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import static ch.jalu.configme.properties.PropertyInitializer.newListProperty;
import static ch.jalu.configme.properties.PropertyInitializer.newProperty;
@@ -73,6 +76,7 @@ public class SettingsMigrationService extends PlainMigrationService {
| hasSupportOldPasswordProperty(resource)
| convertToRegistrationType(resource)
| mergeAndMovePermissionGroupSettings(resource)
| moveDeprecatedHashAlgorithmIntoLegacySection(resource)
|| hasDeprecatedProperties(resource);
}
@@ -286,6 +290,31 @@ public class SettingsMigrationService extends PlainMigrationService {
return performedChanges;
}
/**
* If a deprecated hash is used, it is added to the legacy hashes option and the active hash
* is changed to SHA256.
*
* @param resource The property resource
* @return True if the configuration has changed, false otherwise
*/
private static boolean moveDeprecatedHashAlgorithmIntoLegacySection(PropertyResource resource) {
HashAlgorithm currentHash = SecuritySettings.PASSWORD_HASH.getValue(resource);
// Skip CUSTOM (has no class) and PLAINTEXT (is force-migrated later on in the startup process)
if (currentHash != HashAlgorithm.CUSTOM && currentHash != HashAlgorithm.PLAINTEXT) {
Class<? extends EncryptionMethod> clazz = currentHash.getClazz();
if (clazz.isAnnotationPresent(Deprecated.class)) {
resource.setValue(SecuritySettings.PASSWORD_HASH.getPath(), HashAlgorithm.SHA256);
Set<HashAlgorithm> legacyHashes = SecuritySettings.LEGACY_HASHES.getValue(resource);
legacyHashes.add(currentHash);
resource.setValue(SecuritySettings.LEGACY_HASHES.getPath(), legacyHashes);
ConsoleLogger.warning("The hash algorithm '" + currentHash
+ "' is no longer supported for active use. New hashes will be in SHA256.");
return true;
}
}
return false;
}
/**
* Checks for an old property path and moves it to a new path if it is present and the new path is not yet set.
*
@@ -53,7 +53,7 @@ public final class SecuritySettings implements SettingsHolder {
newProperty("settings.security.passwordMaxLength", 30);
@Comment({
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512, WHIRLPOOL,",
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at",
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md"