From bf387827907c482b0ee50be6735ad10c1a3a6c50 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Fri, 14 Apr 2017 18:03:27 +0200 Subject: [PATCH] Implement ARGON2 hash (#1165) * Implement ARGON2 hash #1150 * Fix argon hash verify * Add argon2 test * #1150 Account for Argon2 managing salts internally --- docs/hash_algorithms.md | 5 +-- pom.xml | 15 +++++++++ .../xephi/authme/security/HashAlgorithm.java | 1 + .../xephi/authme/security/crypts/Argon2.java | 31 +++++++++++++++++++ .../authme/security/crypts/Argon2Test.java | 21 +++++++++++++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fr/xephi/authme/security/crypts/Argon2.java create mode 100644 src/test/java/fr/xephi/authme/security/crypts/Argon2Test.java diff --git a/docs/hash_algorithms.md b/docs/hash_algorithms.md index 8e066dc7f..ef05a2515 100644 --- a/docs/hash_algorithms.md +++ b/docs/hash_algorithms.md @@ -1,5 +1,5 @@ - + ## Hash Algorithms AuthMe supports the following hash algorithms for storing your passwords safely. @@ -7,6 +7,7 @@ AuthMe supports the following hash algorithms for storing your passwords safely. Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? --------- | -------------- | ----------- | ----- | --- | --------- | ------ | --------- +ARGON2 | Recommended | 96 | | | None | | BCRYPT | Recommended | 60 | | | Text | | BCRYPT2Y | Recommended | 60 | | | Text | 22 | CRAZYCRYPT1 | Do not use | 128 | | | Username | | @@ -82,4 +83,4 @@ or bad. --- -This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Sat Mar 25 00:15:27 CET 2017 +This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Fri Apr 14 01:40:05 CEST 2017 diff --git a/pom.xml b/pom.xml index c46ef85f2..52115a891 100644 --- a/pom.xml +++ b/pom.xml @@ -264,6 +264,10 @@ de.rtner fr.xephi.authme.libs.de.rtner + + de.mkammerer + fr.xephi.authme.libs.de.mkammerer + javax.inject fr.xephi.authme.libs.javax.inject @@ -319,6 +323,10 @@ de.rtner fr.xephi.authme.libs.de.rtner + + de.mkammerer + fr.xephi.authme.libs.de.mkammerer + javax.inject fr.xephi.authme.libs.javax.inject @@ -537,6 +545,13 @@ 1.1.2 + + + de.mkammerer + argon2-jvm + 2.2 + + diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java index f12da678d..909d2443d 100644 --- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java +++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java @@ -7,6 +7,7 @@ import fr.xephi.authme.security.crypts.EncryptionMethod; */ public enum HashAlgorithm { + ARGON2(fr.xephi.authme.security.crypts.Argon2.class), BCRYPT(fr.xephi.authme.security.crypts.BCrypt.class), BCRYPT2Y(fr.xephi.authme.security.crypts.BCrypt2y.class), CRAZYCRYPT1(fr.xephi.authme.security.crypts.CrazyCrypt1.class), diff --git a/src/main/java/fr/xephi/authme/security/crypts/Argon2.java b/src/main/java/fr/xephi/authme/security/crypts/Argon2.java new file mode 100644 index 000000000..55ab3d8a0 --- /dev/null +++ b/src/main/java/fr/xephi/authme/security/crypts/Argon2.java @@ -0,0 +1,31 @@ +package fr.xephi.authme.security.crypts; + +import de.mkammerer.argon2.Argon2Constants; +import de.mkammerer.argon2.Argon2Factory; +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(); + } + + @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); + } +} diff --git a/src/test/java/fr/xephi/authme/security/crypts/Argon2Test.java b/src/test/java/fr/xephi/authme/security/crypts/Argon2Test.java new file mode 100644 index 000000000..0a46003c7 --- /dev/null +++ b/src/test/java/fr/xephi/authme/security/crypts/Argon2Test.java @@ -0,0 +1,21 @@ +package fr.xephi.authme.security.crypts; + +/** + * Test for {@link Argon2}. + */ +public class Argon2Test extends AbstractEncryptionMethodTest { + + 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(íù* + } + + @Override + protected boolean testHashEqualityForSameSalt() { + // Argon2 has a salt but it is handled internally + return false; + } +}