Add password4j implementation of PasswordEncoder
This commit is contained in:
@@ -463,6 +463,115 @@ There are a significant number of other `PasswordEncoder` implementations that e
|
||||
They are all deprecated to indicate that they are no longer considered secure.
|
||||
However, there are no plans to remove them, since it is difficult to migrate existing legacy systems.
|
||||
|
||||
[[password4j]]
|
||||
== Password4j-based Password Encoders
|
||||
|
||||
Spring Security 7.0 introduces alternative password encoder implementations based on the https://github.com/Password4j/password4j[Password4j] library.
|
||||
These encoders provide additional options for popular hashing algorithms and can be used as alternatives to the existing Spring Security implementations.
|
||||
|
||||
The Password4j library is a Java cryptographic library that focuses on password hashing with support for multiple algorithms.
|
||||
These encoders are particularly useful when you need specific algorithm configurations or want to leverage Password4j's optimizations.
|
||||
|
||||
All Password4j-based encoders are thread-safe and can be shared across multiple threads.
|
||||
|
||||
[[password4j-argon2]]
|
||||
=== Argon2Password4jPasswordEncoder
|
||||
|
||||
The `Argon2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Argon2[Argon2] algorithm via the Password4j library to hash passwords.
|
||||
This provides an alternative to Spring Security's built-in `Argon2PasswordEncoder` with different configuration options and potential performance characteristics.
|
||||
|
||||
Argon2 is the winner of the https://en.wikipedia.org/wiki/Password_Hashing_Competition[Password Hashing Competition] and is recommended for new applications.
|
||||
This implementation leverages Password4j's Argon2 support which properly includes the salt in the output hash.
|
||||
|
||||
Create an encoder with default settings:
|
||||
|
||||
.Argon2Password4jPasswordEncoder
|
||||
include-code::./Argon2UsageTests[tag=default-params,indent=0]
|
||||
|
||||
Create an encoder with custom Argon2 parameters:
|
||||
|
||||
.Argon2Password4jPasswordEncoder Custom
|
||||
include-code::./Argon2UsageTests[tag=custom-params,indent=0]
|
||||
|
||||
[[password4j-bcrypt]]
|
||||
=== BcryptPassword4jPasswordEncoder
|
||||
|
||||
The `BcryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Bcrypt[BCrypt] algorithm via the Password4j library to hash passwords.
|
||||
This provides an alternative to Spring Security's built-in `BCryptPasswordEncoder` with Password4j's implementation characteristics.
|
||||
|
||||
BCrypt is a well-established password hashing algorithm that includes built-in salt generation and is resistant to rainbow table attacks.
|
||||
This implementation leverages Password4j's BCrypt support which properly includes the salt in the output hash.
|
||||
|
||||
Create an encoder with default settings:
|
||||
|
||||
.BcryptPassword4jPasswordEncoder
|
||||
include-code::./BcryptUsageTests[tag=default-params,indent=0]
|
||||
|
||||
Create an encoder with custom bcrypt parameters:
|
||||
|
||||
.BcryptPassword4jPasswordEncoder Custom
|
||||
include-code::./BcryptUsageTests[tag=custom-params,indent=0]
|
||||
|
||||
[[password4j-scrypt]]
|
||||
=== ScryptPassword4jPasswordEncoder
|
||||
|
||||
The `ScryptPassword4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/Scrypt[SCrypt] algorithm via the Password4j library to hash passwords.
|
||||
This provides an alternative to Spring Security's built-in `SCryptPasswordEncoder` with Password4j's implementation characteristics.
|
||||
|
||||
SCrypt is a memory-hard password hashing algorithm designed to be resistant to hardware brute-force attacks.
|
||||
This implementation leverages Password4j's SCrypt support which properly includes the salt in the output hash.
|
||||
|
||||
|
||||
Create an encoder with default settings:
|
||||
|
||||
.ScryptPassword4jPasswordEncoder
|
||||
include-code::./ScryptUsageTests[tag=default-params,indent=0]
|
||||
|
||||
Create an encoder with custom scrypt parameters:
|
||||
|
||||
.ScryptPassword4jPasswordEncoder Custom
|
||||
include-code::./ScryptUsageTests[tag=custom-params,indent=0]
|
||||
|
||||
[[password4j-pbkdf2]]
|
||||
=== Pbkdf2Password4jPasswordEncoder
|
||||
|
||||
The `Pbkdf2Password4jPasswordEncoder` implementation uses the https://en.wikipedia.org/wiki/PBKDF2[PBKDF2] algorithm via the Password4j library to hash passwords.
|
||||
This provides an alternative to Spring Security's built-in `Pbkdf2PasswordEncoder` with explicit salt management.
|
||||
|
||||
PBKDF2 is a key derivation function designed to be computationally expensive to thwart dictionary and brute force attacks.
|
||||
This implementation handles salt management explicitly since Password4j's PBKDF2 implementation does not include the salt in the output hash.
|
||||
The encoded password format is: `+{salt}:{hash}+` where both salt and hash are Base64 encoded.
|
||||
|
||||
Create an encoder with default settings:
|
||||
|
||||
.Pbkdf2Password4jPasswordEncoder
|
||||
include-code::./Pbkdf2UsageTests[tag=default-params,indent=0]
|
||||
|
||||
Create an encoder with custom PBKDF2 parameters:
|
||||
|
||||
.Pbkdf2Password4jPasswordEncoder Custom
|
||||
include-code::./Pbkdf2UsageTests[tag=custom-params,indent=0]
|
||||
|
||||
[[password4j-ballooning]]
|
||||
=== BalloonHashingPassword4jPasswordEncoder
|
||||
|
||||
The `BalloonHashingPassword4jPasswordEncoder` implementation uses the Balloon hashing algorithm via the Password4j library to hash passwords.
|
||||
Balloon hashing is a memory-hard password hashing algorithm designed to be resistant to both time-memory trade-off attacks and side-channel attacks.
|
||||
|
||||
This implementation handles salt management explicitly since Password4j's Balloon hashing implementation does not include the salt in the output hash.
|
||||
The encoded password format is: `+{salt}:{hash}+` where both salt and hash are Base64 encoded.
|
||||
|
||||
|
||||
Create an encoder with default settings:
|
||||
|
||||
.BalloonHashingPassword4jPasswordEncoder
|
||||
include-code::./BallooningHashingUsageTests[tag=default-params,indent=0]
|
||||
|
||||
Create an encoder with custom parameters:
|
||||
|
||||
.BalloonHashingPassword4jPasswordEncoder Custom
|
||||
include-code::./BallooningHashingUsageTests[tag=custom-params,indent=0]
|
||||
|
||||
[[authentication-password-storage-configuration]]
|
||||
== Password Storage Configuration
|
||||
|
||||
|
||||
@@ -35,6 +35,15 @@ Java::
|
||||
http.csrf((csrf) -> csrf.spa());
|
||||
----
|
||||
|
||||
== Crypto
|
||||
|
||||
* Added Password4j-based password encoders providing alternative implementations for popular hashing algorithms:
|
||||
** `Argon2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#password4j-argon2[Argon2]
|
||||
** `BcryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#password4j-bcrypt[BCrypt]
|
||||
** `ScryptPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#password4j-scrypt[SCrypt]
|
||||
** `Pbkdf2Password4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#password4j-pbkdf2[PBKDF2]
|
||||
** `BalloonHashingPassword4jPasswordEncoder` - xref:features/authentication/password-storage.adoc#password4j-balloon[Balloon Hashing]
|
||||
|
||||
== Data
|
||||
|
||||
* Added support to Authorized objects for Spring Data types
|
||||
|
||||
@@ -39,6 +39,7 @@ dependencies {
|
||||
testImplementation project(':spring-security-test')
|
||||
testImplementation project(':spring-security-oauth2-client')
|
||||
testImplementation 'com.squareup.okhttp3:mockwebserver'
|
||||
testImplementation libs.com.password4j.password4j
|
||||
testImplementation 'com.unboundid:unboundid-ldapsdk'
|
||||
testImplementation libs.webauthn4j.core
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-reflect'
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.docs.features.authentication.password4jargon2;
|
||||
|
||||
import com.password4j.Argon2Function;
|
||||
import com.password4j.types.Argon2;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password4j.Argon2Password4jPasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class Argon2UsageTests {
|
||||
|
||||
@Test
|
||||
void defaultParams() {
|
||||
// tag::default-params[]
|
||||
PasswordEncoder encoder = new Argon2Password4jPasswordEncoder();
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void customParameters() {
|
||||
// tag::custom-params[]
|
||||
Argon2Function argon2Fn = Argon2Function.getInstance(65536, 3, 4, 32,
|
||||
Argon2.ID);
|
||||
PasswordEncoder encoder = new Argon2Password4jPasswordEncoder(argon2Fn);
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::custom-params[]
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.docs.features.authentication.password4jballooning;
|
||||
|
||||
import com.password4j.BalloonHashingFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password4j.BalloonHashingPassword4jPasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class BallooningHashingUsageTests {
|
||||
|
||||
@Test
|
||||
void defaultParams() {
|
||||
// tag::default-params[]
|
||||
PasswordEncoder encoder = new BalloonHashingPassword4jPasswordEncoder();
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void customParameters() {
|
||||
// tag::custom-params[]
|
||||
BalloonHashingFunction ballooningHashingFn =
|
||||
BalloonHashingFunction.getInstance("SHA-256", 1024, 3, 4, 3);
|
||||
PasswordEncoder encoder = new BalloonHashingPassword4jPasswordEncoder(ballooningHashingFn);
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::custom-params[]
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.docs.features.authentication.password4jbcrypt;
|
||||
|
||||
import com.password4j.BcryptFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password4j.BcryptPassword4jPasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class BcryptUsageTests {
|
||||
|
||||
@Test
|
||||
void defaultParams() {
|
||||
// tag::default-params[]
|
||||
PasswordEncoder encoder = new BCryptPasswordEncoder();
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void customParameters() {
|
||||
// tag::custom-params[]
|
||||
BcryptFunction bcryptFn = BcryptFunction.getInstance(12);
|
||||
PasswordEncoder encoder = new BcryptPassword4jPasswordEncoder(bcryptFn);
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::custom-params[]
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.docs.features.authentication.password4jpbkdf2;
|
||||
|
||||
import com.password4j.PBKDF2Function;
|
||||
import com.password4j.types.Hmac;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password4j.Pbkdf2Password4jPasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class Pbkdf2UsageTests {
|
||||
|
||||
@Test
|
||||
void defaultParams() {
|
||||
// tag::default-params[]
|
||||
PasswordEncoder encoder = new Pbkdf2Password4jPasswordEncoder();
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void customParameters() {
|
||||
// tag::custom-params[]
|
||||
PBKDF2Function pbkdf2Fn = PBKDF2Function.getInstance(Hmac.SHA256, 100000, 256);
|
||||
PasswordEncoder encoder = new Pbkdf2Password4jPasswordEncoder(pbkdf2Fn);
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::custom-params[]
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.docs.features.authentication.password4jscrypt;
|
||||
|
||||
import com.password4j.ScryptFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password4j.ScryptPassword4jPasswordEncoder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class ScryptUsageTests {
|
||||
|
||||
@Test
|
||||
void defaultParams() {
|
||||
// tag::default-params[]
|
||||
PasswordEncoder encoder = new ScryptPassword4jPasswordEncoder();
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
void customParameters() {
|
||||
// tag::custom-params[]
|
||||
ScryptFunction scryptFn = ScryptFunction.getInstance(32768, 8, 1, 32);
|
||||
PasswordEncoder encoder = new ScryptPassword4jPasswordEncoder(scryptFn);
|
||||
String result = encoder.encode("myPassword");
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue();
|
||||
// end::custom-params[]
|
||||
}
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.kt.docs.features.authentication.password4jargon2
|
||||
|
||||
import com.password4j.Argon2Function
|
||||
import com.password4j.types.Argon2
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.crypto.password4j.Argon2Password4jPasswordEncoder
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class Argon2UsageTests {
|
||||
|
||||
@Test
|
||||
fun defaultParams() {
|
||||
// tag::default-params[]
|
||||
val encoder: PasswordEncoder = Argon2Password4jPasswordEncoder()
|
||||
val result = encoder.encode("myPassword")
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customParameters() {
|
||||
// tag::custom-params[]
|
||||
val argon2Fn = Argon2Function.getInstance(
|
||||
65536, 3, 4, 32,
|
||||
Argon2.ID
|
||||
)
|
||||
val encoder: PasswordEncoder = Argon2Password4jPasswordEncoder(argon2Fn)
|
||||
val result = encoder.encode("myPassword")
|
||||
assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::custom-params[]
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.security.kt.docs.features.authentication.password4jballooning
|
||||
|
||||
import com.password4j.BalloonHashingFunction
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.crypto.password4j.BalloonHashingPassword4jPasswordEncoder
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class BallooningHashingUsageTests {
|
||||
@Test
|
||||
fun defaultParams() {
|
||||
// tag::default-params[]
|
||||
val encoder: PasswordEncoder = BalloonHashingPassword4jPasswordEncoder()
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customParameters() {
|
||||
// tag::custom-params[]
|
||||
val ballooningHashingFn =
|
||||
BalloonHashingFunction.getInstance("SHA-256", 1024, 3, 4, 3)
|
||||
val encoder: PasswordEncoder = BalloonHashingPassword4jPasswordEncoder(ballooningHashingFn)
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::custom-params[]
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.springframework.security.kt.docs.features.authentication.password4jbcrypt
|
||||
|
||||
import com.password4j.BcryptFunction
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.crypto.password4j.BcryptPassword4jPasswordEncoder
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class BcryptUsageTests {
|
||||
@Test
|
||||
fun defaultParams() {
|
||||
// tag::default-params[]
|
||||
val encoder: PasswordEncoder = BCryptPasswordEncoder()
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customParameters() {
|
||||
// tag::custom-params[]
|
||||
val bcryptFunction = BcryptFunction.getInstance(12)
|
||||
val encoder: PasswordEncoder = BcryptPassword4jPasswordEncoder(bcryptFunction)
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::custom-params[]
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.springframework.security.kt.docs.features.authentication.password4jpbkdf2
|
||||
|
||||
import com.password4j.PBKDF2Function
|
||||
import com.password4j.types.Hmac
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.crypto.password4j.Pbkdf2Password4jPasswordEncoder
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class Pbkdf2UsageTests {
|
||||
@Test
|
||||
fun defaultParams() {
|
||||
// tag::default-params[]
|
||||
val encoder: PasswordEncoder = Pbkdf2Password4jPasswordEncoder()
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customParameters() {
|
||||
// tag::custom-params[]
|
||||
val pbkdf2Fn = PBKDF2Function.getInstance(Hmac.SHA256, 100000, 256)
|
||||
val encoder: PasswordEncoder = Pbkdf2Password4jPasswordEncoder(pbkdf2Fn)
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::custom-params[]
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package org.springframework.security.kt.docs.features.authentication.password4jscrypt
|
||||
|
||||
import com.password4j.ScryptFunction
|
||||
import org.assertj.core.api.Assertions
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.security.crypto.password.PasswordEncoder
|
||||
import org.springframework.security.crypto.password4j.ScryptPassword4jPasswordEncoder
|
||||
|
||||
/**
|
||||
* @author Rob Winch
|
||||
*/
|
||||
class ScryptUsageTests {
|
||||
@Test
|
||||
fun defaultParams() {
|
||||
// tag::default-params[]
|
||||
val encoder: PasswordEncoder = ScryptPassword4jPasswordEncoder()
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::default-params[]
|
||||
}
|
||||
|
||||
@Test
|
||||
fun customParameters() {
|
||||
// tag::custom-params[]
|
||||
val scryptFn = ScryptFunction.getInstance(32768, 8, 1, 32)
|
||||
val encoder: PasswordEncoder = ScryptPassword4jPasswordEncoder(scryptFn)
|
||||
val result = encoder.encode("myPassword")
|
||||
Assertions.assertThat(encoder.matches("myPassword", result)).isTrue()
|
||||
// end::custom-params[]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user