#1150 - Add Argon2 support
- Add argon2 implementation - Extract argon2 library check to method on Argon 2 - Add link to Wiki page on errors - Check within Argon2Test if the test cases should be run, not in the abstract parent
This commit is contained in:
parent
90a7b47217
commit
8fe92da119
@ -1,12 +1,17 @@
|
|||||||
sudo: false
|
sudo: required
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- oracle-java8-installer
|
- oracle-java8-installer
|
||||||
|
- git
|
||||||
|
|
||||||
language: java
|
language: java
|
||||||
jdk: oraclejdk8
|
jdk: oraclejdk8
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- "sudo git clone https://www.github.com/P-H-C/phc-winner-argon2.git argon2-src"
|
||||||
|
- "cd argon2-src && sudo make && sudo make install && cd .."
|
||||||
|
|
||||||
script: mvn clean verify -B
|
script: mvn clean verify -B
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
machine:
|
machine:
|
||||||
java:
|
java:
|
||||||
version: oraclejdk8
|
version: oraclejdk8
|
||||||
|
dependencies:
|
||||||
|
pre:
|
||||||
|
- "sudo apt-get update; sudo apt-get install -y git; sudo git clone https://www.github.com/P-H-C/phc-winner-argon2.git argon2-src; cd argon2-src; sudo make; sudo make install"
|
||||||
general:
|
general:
|
||||||
artifacts:
|
artifacts:
|
||||||
- "target/AuthMe-*.jar"
|
- "target/AuthMe-*.jar"
|
||||||
|
|||||||
@ -7,6 +7,7 @@ AuthMe supports the following hash algorithms for storing your passwords safely.
|
|||||||
|
|
||||||
Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate?
|
Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate?
|
||||||
--------- | -------------- | ----------- | ----- | --- | --------- | ------ | ---------
|
--------- | -------------- | ----------- | ----- | --- | --------- | ------ | ---------
|
||||||
|
ARGON2 | Recommended | 96 | | | Text | 16 |
|
||||||
BCRYPT | Recommended | 60 | | | Text | |
|
BCRYPT | Recommended | 60 | | | Text | |
|
||||||
BCRYPT2Y | Recommended | 60 | | | Text | 22 |
|
BCRYPT2Y | Recommended | 60 | | | Text | 22 |
|
||||||
CRAZYCRYPT1 | Do not use | 128 | | | Username | |
|
CRAZYCRYPT1 | Do not use | 128 | | | Username | |
|
||||||
|
|||||||
11
pom.xml
11
pom.xml
@ -192,6 +192,10 @@
|
|||||||
<pattern>de.rtner</pattern>
|
<pattern>de.rtner</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.de.rtner</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.de.rtner</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>de.mkammerer</pattern>
|
||||||
|
<shadedPattern>fr.xephi.authme.libs.de.mkammerer</shadedPattern>
|
||||||
|
</relocation>
|
||||||
<relocation>
|
<relocation>
|
||||||
<pattern>javax.inject</pattern>
|
<pattern>javax.inject</pattern>
|
||||||
<shadedPattern>fr.xephi.authme.libs.javax.inject</shadedPattern>
|
<shadedPattern>fr.xephi.authme.libs.javax.inject</shadedPattern>
|
||||||
@ -388,6 +392,13 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Argon2 implementation -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>de.mkammerer</groupId>
|
||||||
|
<artifactId>argon2-jvm-nolibs</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Spigot API, http://www.spigotmc.org/ -->
|
<!-- Spigot API, http://www.spigotmc.org/ -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
|
|||||||
@ -23,6 +23,8 @@ import fr.xephi.authme.listener.PlayerListener18;
|
|||||||
import fr.xephi.authme.listener.PlayerListener19;
|
import fr.xephi.authme.listener.PlayerListener19;
|
||||||
import fr.xephi.authme.listener.PlayerListener19Spigot;
|
import fr.xephi.authme.listener.PlayerListener19Spigot;
|
||||||
import fr.xephi.authme.listener.ServerListener;
|
import fr.xephi.authme.listener.ServerListener;
|
||||||
|
import fr.xephi.authme.security.HashAlgorithm;
|
||||||
|
import fr.xephi.authme.security.crypts.Argon2;
|
||||||
import fr.xephi.authme.security.crypts.Sha256;
|
import fr.xephi.authme.security.crypts.Sha256;
|
||||||
import fr.xephi.authme.service.BackupService;
|
import fr.xephi.authme.service.BackupService;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
@ -267,6 +269,13 @@ public class AuthMe extends JavaPlugin {
|
|||||||
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
|
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
|
||||||
ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
|
ConsoleLogger.warning("Note: You have set Email.useTls to false but this only affects mail over port 25");
|
||||||
}
|
}
|
||||||
|
// Check if argon2 library is present and can be loaded
|
||||||
|
if (settings.getProperty(SecuritySettings.PASSWORD_HASH).equals(HashAlgorithm.ARGON2)
|
||||||
|
&& !Argon2.isLibraryLoaded()) {
|
||||||
|
ConsoleLogger.warning("WARNING!!! You use Argon2 Hash Algorithm method but we can't find the Argon2 "
|
||||||
|
+ "library on your system! See https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash");
|
||||||
|
stopOrUnload();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import fr.xephi.authme.security.crypts.EncryptionMethod;
|
|||||||
*/
|
*/
|
||||||
public enum HashAlgorithm {
|
public enum HashAlgorithm {
|
||||||
|
|
||||||
|
ARGON2(fr.xephi.authme.security.crypts.Argon2.class),
|
||||||
BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class),
|
BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class),
|
||||||
BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class),
|
BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class),
|
||||||
CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class),
|
CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class),
|
||||||
|
|||||||
48
src/main/java/fr/xephi/authme/security/crypts/Argon2.java
Normal file
48
src/main/java/fr/xephi/authme/security/crypts/Argon2.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package fr.xephi.authme.security.crypts;
|
||||||
|
|
||||||
|
import de.mkammerer.argon2.Argon2Constants;
|
||||||
|
import de.mkammerer.argon2.Argon2Factory;
|
||||||
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.security.crypts.description.HasSalt;
|
||||||
|
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||||
|
import fr.xephi.authme.security.crypts.description.SaltType;
|
||||||
|
import fr.xephi.authme.security.crypts.description.Usage;
|
||||||
|
|
||||||
|
@Recommendation(Usage.RECOMMENDED)
|
||||||
|
@HasSalt(value = SaltType.TEXT, length = Argon2Constants.DEFAULT_SALT_LENGTH)
|
||||||
|
// Note: Argon2 is actually a salted algorithm but salt generation is handled internally
|
||||||
|
// and isn't exposed to the outside, so we treat it as an unsalted implementation
|
||||||
|
public class Argon2 extends UnsaltedMethod {
|
||||||
|
|
||||||
|
private de.mkammerer.argon2.Argon2 argon2;
|
||||||
|
|
||||||
|
public Argon2() {
|
||||||
|
argon2 = Argon2Factory.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the argon2 library is available in java.library.path.
|
||||||
|
*
|
||||||
|
* @return true if the library is present, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isLibraryLoaded() {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("argon2");
|
||||||
|
return true;
|
||||||
|
} catch (UnsatisfiedLinkError e) {
|
||||||
|
ConsoleLogger.logException(
|
||||||
|
"Cannot find argon2 library: https://github.com/AuthMe/AuthMeReloaded/wiki/Argon2-as-Password-Hash", e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String computeHash(String password) {
|
||||||
|
return argon2.hash(2, 65536, 1, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean comparePassword(String password, HashedPassword hashedPassword, String name) {
|
||||||
|
return argon2.verify(hashedPassword.getHash(), password);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -55,8 +55,9 @@ public final class SecuritySettings implements SettingsHolder {
|
|||||||
@Comment({
|
@Comment({
|
||||||
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
|
"Possible values: SHA256, BCRYPT, BCRYPT2Y, PBKDF2, SALTEDSHA512,",
|
||||||
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
|
"MYBB, IPB3, PHPBB, PHPFUSION, SMF, XENFORO, XAUTH, JOOMLA, WBB3, WBB4, MD5VB,",
|
||||||
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM (for developers only). See full list at",
|
"PBKDF2DJANGO, WORDPRESS, ROYALAUTH, ARGON2, CUSTOM (for developers only). See full list at",
|
||||||
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md"
|
"https://github.com/AuthMe/AuthMeReloaded/blob/master/docs/hash_algorithms.md",
|
||||||
|
"If you use ARGON2, check that you have the argon2 c library on your system"
|
||||||
})
|
})
|
||||||
public static final Property<HashAlgorithm> PASSWORD_HASH =
|
public static final Property<HashAlgorithm> PASSWORD_HASH =
|
||||||
newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256);
|
newProperty(HashAlgorithm.class, "settings.security.passwordHash", HashAlgorithm.SHA256);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package fr.xephi.authme.security;
|
|||||||
|
|
||||||
import ch.jalu.injector.Injector;
|
import ch.jalu.injector.Injector;
|
||||||
import ch.jalu.injector.InjectorBuilder;
|
import ch.jalu.injector.InjectorBuilder;
|
||||||
|
import fr.xephi.authme.security.crypts.Argon2;
|
||||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||||
@ -61,6 +62,10 @@ public class HashAlgorithmIntegrationTest {
|
|||||||
// given / when / then
|
// given / when / then
|
||||||
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
||||||
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
if (!HashAlgorithm.CUSTOM.equals(algorithm) && !HashAlgorithm.PLAINTEXT.equals(algorithm)) {
|
||||||
|
if (HashAlgorithm.ARGON2.equals(algorithm) && !Argon2.isLibraryLoaded()) {
|
||||||
|
System.out.println("[WARNING] Cannot find argon2 library, skipping integration test");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
EncryptionMethod method = injector.createIfHasDependencies(algorithm.getClazz());
|
EncryptionMethod method = injector.createIfHasDependencies(algorithm.getClazz());
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
fail("Could not create '" + algorithm.getClazz() + "' - forgot to provide some class?");
|
fail("Could not create '" + algorithm.getClazz() + "' - forgot to provide some class?");
|
||||||
|
|||||||
@ -0,0 +1,29 @@
|
|||||||
|
package fr.xephi.authme.security.crypts;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.junit.Assume.assumeThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for {@link Argon2}.
|
||||||
|
*/
|
||||||
|
public class Argon2Test extends AbstractEncryptionMethodTest {
|
||||||
|
|
||||||
|
private static final boolean IS_LIBRARY_LOADED = Argon2.isLibraryLoaded();
|
||||||
|
|
||||||
|
public Argon2Test() {
|
||||||
|
super(new Argon2(),
|
||||||
|
"$argon2i$v=19$m=65536,t=2,p=1$dOP8NiXsPTcMgzI4Z8Rbew$ShdowtoTEWTL5UTFz1UgQOigb9JOlm4ZxWPA6WbIeUw", // password
|
||||||
|
"$argon2i$v=19$m=65536,t=2,p=1$amZHbPfgc5peKd/4w1AI1g$Q2PUiOVw47TACijP57U0xf7QfiZ00HV4eFzMDA6yKRE", // PassWord1
|
||||||
|
"$argon2i$v=19$m=65536,t=2,p=1$58v7dWNn9/bpD00QLzSebw$7cMC7p0qceE3Mgf2yQp4X7c+UkO9oyJwQ7S6XTBubNs", // &^%te$t?Pw@_
|
||||||
|
"$argon2i$v=19$m=65536,t=2,p=1$93OSU71DgBOzpmhti7+6rQ$sSSI6QQQdoG9DlGwLjYz576kTek89nwr9CyNpy6bsL0"); // âË_3(íù*
|
||||||
|
|
||||||
|
assumeThat("Argon2 library is not loaded - skipping test",
|
||||||
|
IS_LIBRARY_LOADED, equalTo(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean testHashEqualityForSameSalt() {
|
||||||
|
// Argon2 has a salt but it is handled internally
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user