Merge branch '5.8.x' into 6.0.x

Closes gh-13406
This commit is contained in:
Rob Winch
2023-06-18 21:33:58 -05:00
116 changed files with 4826 additions and 3206 deletions

View File

@@ -23,19 +23,22 @@ Both `BytesEncryptor` and `TextEncryptor` are interfaces. `BytesEncryptor` has m
You can use the `Encryptors.stronger` factory method to construct a `BytesEncryptor`:
.BytesEncryptor
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
Encryptors.stronger("password", "salt");
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
Encryptors.stronger("password", "salt")
----
====
======
The `stronger` encryption method creates an encryptor by using 256-bit AES encryption with
Galois Counter Mode (GCM).
@@ -49,19 +52,22 @@ The provided salt should be in hex-encoded String form, be random, and be at lea
You can generate such a salt by using a `KeyGenerator`:
.Generating a key
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
val salt = KeyGenerators.string().generateKey() // generates a random 8-byte salt that is then hex-encoded
----
====
======
You can also use the `standard` encryption method, which is 256-bit AES in Cipher Block Chaining (CBC) Mode.
This mode is not https://en.wikipedia.org/wiki/Authenticated_encryption[authenticated] and does not provide any
@@ -73,19 +79,22 @@ For a more secure alternative, use `Encryptors.stronger`.
You can use the `Encryptors.text` factory method to construct a standard TextEncryptor:
.TextEncryptor
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
Encryptors.text("password", "salt");
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
Encryptors.text("password", "salt")
----
====
======
A `TextEncryptor` uses a standard `BytesEncryptor` to encrypt text data.
Encrypted results are returned as hex-encoded strings for easy storage on the filesystem or in a database.
@@ -101,81 +110,92 @@ You can also construct a {security-api-url}org/springframework/security/crypto/k
You can use the `KeyGenerators.secureRandom` factory methods to generate a `BytesKeyGenerator` backed by a `SecureRandom` instance:
.BytesKeyGenerator
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
BytesKeyGenerator generator = KeyGenerators.secureRandom();
byte[] key = generator.generateKey();
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()
----
====
======
The default key length is 8 bytes.
A `KeyGenerators.secureRandom` variant provides control over the key length:
.KeyGenerators.secureRandom
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
KeyGenerators.secureRandom(16);
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
KeyGenerators.secureRandom(16)
----
====
======
Use the `KeyGenerators.shared` factory method to construct a BytesKeyGenerator that always returns the same key on every invocation:
.KeyGenerators.shared
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
KeyGenerators.shared(16);
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
KeyGenerators.shared(16)
----
====
======
=== StringKeyGenerator
You can use the `KeyGenerators.string` factory method to construct an 8-byte, `SecureRandom` `KeyGenerator` that hex-encodes each key as a `String`:
.StringKeyGenerator
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
KeyGenerators.string();
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
KeyGenerators.string()
----
====
======
[[spring-security-crypto-passwordencoders]]
== Password Encoding
The password package of the `spring-security-crypto` module provides support for encoding passwords.
`PasswordEncoder` is the central service interface and has the following signature:
====
[source,java]
----
public interface PasswordEncoder {
@@ -188,7 +208,6 @@ public interface PasswordEncoder {
}
}
----
====
The `matches` method returns true if the `rawPassword`, once encoded, equals the `encodedPassword`.
This method is designed to support password-based authentication schemes.
@@ -202,8 +221,10 @@ You can change this value in your deployed system without affecting existing pas
The following example uses the `BCryptPasswordEncoder`:
.BCryptPasswordEncoder
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@@ -213,7 +234,8 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
@@ -222,7 +244,7 @@ val encoder = BCryptPasswordEncoder(16)
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
======
The `Pbkdf2PasswordEncoder` implementation uses PBKDF2 algorithm to hash the passwords.
To defeat password cracking, PBKDF2 is a deliberately slow algorithm and should be tuned to take about .5 seconds to verify a password on your system.
@@ -230,8 +252,10 @@ The following system uses the `Pbkdf2PasswordEncoder`:
.Pbkdf2PasswordEncoder
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
// Create an encoder with all the defaults
@@ -240,7 +264,8 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
@@ -248,4 +273,4 @@ val encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
======