diff --git a/core-java-modules/core-java-security-3/pom.xml b/core-java-modules/core-java-security-3/pom.xml
index fef8b53289..a4f60b4db5 100644
--- a/core-java-modules/core-java-security-3/pom.xml
+++ b/core-java-modules/core-java-security-3/pom.xml
@@ -30,12 +30,18 @@
jaxb-api
${jaxb-api.version}
+
+ org.springframework.security
+ spring-security-crypto
+ ${spring-security-crypto.version}
+
- 1.60
+ 1.70
1.11
2.3.1
+ 6.0.3
\ No newline at end of file
diff --git a/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java
new file mode 100644
index 0000000000..6e0e326821
--- /dev/null
+++ b/core-java-modules/core-java-security-3/src/test/java/com/baeldung/hash/argon/HashPasswordUnitTest.java
@@ -0,0 +1,65 @@
+package com.baeldung.hash.argon;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
+
+import org.bouncycastle.crypto.generators.Argon2BytesGenerator;
+import org.bouncycastle.crypto.params.Argon2Parameters;
+import org.bouncycastle.util.encoders.Hex;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
+
+import java.util.Arrays;
+import java.util.Base64;
+
+public class HashPasswordUnitTest {
+
+ @Test
+ public void givenRawPassword_whenEncodedWithArgon2_thenMatchesEncodedPassword() {
+ String rawPassword = "Baeldung";
+
+ Argon2PasswordEncoder arg2SpringSecurity = new Argon2PasswordEncoder(16, 32, 1, 60000, 10);
+ String hashPassword = arg2SpringSecurity.encode(rawPassword);
+
+ assertTrue(arg2SpringSecurity.matches(rawPassword, hashPassword));
+ }
+
+ @Test
+ public void givenRawPasswordAndSalt_whenArgon2AlgorithmIsUsed_thenHashIsCorrect() {
+ byte[] salt = generateSalt16Byte();
+ String password = "Baeldung";
+
+ int iterations = 2;
+ int memLimit = 66536;
+ int hashLength = 32;
+ int parallelism = 1;
+ Argon2Parameters.Builder builder = new Argon2Parameters.Builder(Argon2Parameters.ARGON2_id).withVersion(Argon2Parameters.ARGON2_VERSION_13)
+ .withIterations(iterations)
+ .withMemoryAsKB(memLimit)
+ .withParallelism(parallelism)
+ .withSalt(salt);
+
+ Argon2BytesGenerator generate = new Argon2BytesGenerator();
+ generate.init(builder.build());
+ byte[] result = new byte[hashLength];
+ generate.generateBytes(password.getBytes(StandardCharsets.UTF_8), result, 0, result.length);
+
+ Argon2BytesGenerator verifier = new Argon2BytesGenerator();
+ verifier.init(builder.build());
+ byte[] testHash = new byte[hashLength];
+ verifier.generateBytes(password.getBytes(StandardCharsets.UTF_8), testHash, 0, testHash.length);
+
+ assertTrue(Arrays.equals(result, testHash));
+ }
+
+ private static byte[] generateSalt16Byte() {
+ SecureRandom secureRandom = new SecureRandom();
+ byte[] salt = new byte[16];
+ secureRandom.nextBytes(salt);
+ return salt;
+ }
+
+}