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; + } + +}