From 8bf58cff18d68510e27e0dccf490c9792218044f Mon Sep 17 00:00:00 2001
From: Metall <25564543+metallnt@users.noreply.github.com>
Date: Wed, 21 Sep 2022 08:32:53 +0500
Subject: [PATCH 1/3] Create DjangoPasswordVerifier.java
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Верификация PBKDF2_SHA256
---
 .../auth/password/DjangoPasswordVerifier.java | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/DjangoPasswordVerifier.java

diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/DjangoPasswordVerifier.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/DjangoPasswordVerifier.java
new file mode 100644
index 00000000..14f9aef3
--- /dev/null
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/DjangoPasswordVerifier.java
@@ -0,0 +1,42 @@
+package pro.gravit.launchserver.auth.password;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.bouncycastle.crypto.digests.SHA256Digest;
+import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
+import org.bouncycastle.crypto.params.KeyParameter;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public class DjangoPasswordVerifier extends PasswordVerifier {
+    public final Integer DEFAULT_ITERATIONS = 10000;
+    private static final Logger logger = LogManager.getLogger();
+    private static final String algorithm = "pbkdf2_sha256";
+
+    public String getEncodedHash(String password, String salt, int iterations) {
+        PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
+        generator.init(password.getBytes(StandardCharsets.UTF_8), salt.getBytes(), iterations);
+        byte[] dk = ((KeyParameter) generator.generateDerivedParameters(256)).getKey();
+        byte[] hashBase64 = Base64.getEncoder().encode(dk);
+        return new String(hashBase64);
+    }
+
+    public String encode(String password, String salt, int iterations) {
+        String hash = getEncodedHash(password, salt, iterations);
+        return String.format("%s$%d$%s$%s", algorithm, iterations, salt, hash);
+    }
+
+    @Override
+    public boolean check(String encryptedPassword, String password) {
+        String[] params = encryptedPassword.split("\\$");
+        if (params.length != 4) {
+            logger.warn(" end 1 " + params.length);
+            return false;
+        }
+        int iterations = Integer.parseInt(params[1]);
+        String salt = params[2];
+        String hash = encode(password, salt, iterations);
+        return hash.equals(encryptedPassword);
+    }
+}

From 90ee90973e574248a0b910d37ee67d4cb398fee5 Mon Sep 17 00:00:00 2001
From: Metall <25564543+metallnt@users.noreply.github.com>
Date: Wed, 21 Sep 2022 08:40:40 +0500
Subject: [PATCH 2/3] Update PasswordVerifier.java
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Добавил:
1. Способ верификации "django", для осуществления авторизации с помощью PBKDF2 с SHA256.
2. Исключение на отсутствующий алгоритм(NoSuchAlgorithmException)
3. Исключение на неверные ключи(InvalidKeySpecException)
---
 .../gravit/launchserver/auth/password/PasswordVerifier.java | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
index 30c352e9..4f1eaf66 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
@@ -2,6 +2,9 @@
 
 import pro.gravit.utils.ProviderMap;
 
+import java.security.NoSuchAlgorithmException;
+import java.security.spec.InvalidKeySpecException;
+
 public abstract class PasswordVerifier {
     public static final ProviderMap<PasswordVerifier> providers = new ProviderMap<>("PasswordVerifier");
     private static boolean registeredProviders = false;
@@ -14,11 +17,12 @@ public static void registerProviders() {
             providers.register("json", JsonPasswordVerifier.class);
             providers.register("accept", AcceptPasswordVerifier.class);
             providers.register("reject", RejectPasswordVerifier.class);
+            providers.register("django", DjangoPasswordVerifier.class);
             registeredProviders = true;
         }
     }
 
-    public abstract boolean check(String encryptedPassword, String password);
+    public abstract boolean check(String encryptedPassword, String password) throws NoSuchAlgorithmException, InvalidKeySpecException;
 
     public String encrypt(String password) {
         throw new UnsupportedOperationException();

From 66d8b9d9caa5ebd07cb5c4e1d880e52f03651697 Mon Sep 17 00:00:00 2001
From: Metall <25564543+metallnt@users.noreply.github.com>
Date: Wed, 21 Sep 2022 09:29:13 +0500
Subject: [PATCH 3/3] Update PasswordVerifier.java
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Убрал исключения для совместимости
---
 .../gravit/launchserver/auth/password/PasswordVerifier.java  | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
index 4f1eaf66..6617f7fc 100644
--- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
+++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/password/PasswordVerifier.java
@@ -2,9 +2,6 @@
 
 import pro.gravit.utils.ProviderMap;
 
-import java.security.NoSuchAlgorithmException;
-import java.security.spec.InvalidKeySpecException;
-
 public abstract class PasswordVerifier {
     public static final ProviderMap<PasswordVerifier> providers = new ProviderMap<>("PasswordVerifier");
     private static boolean registeredProviders = false;
@@ -22,7 +19,7 @@ public static void registerProviders() {
         }
     }
 
-    public abstract boolean check(String encryptedPassword, String password) throws NoSuchAlgorithmException, InvalidKeySpecException;
+    public abstract boolean check(String encryptedPassword, String password);
 
     public String encrypt(String password) {
         throw new UnsupportedOperationException();