Merge branch '5.7.x' into 5.8.x

Closes gh-13405
This commit is contained in:
Rob Winch
2023-06-18 21:32:35 -05:00
108 changed files with 5712 additions and 3422 deletions

View File

@@ -20,19 +20,22 @@ Encryptors are thread-safe.
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 using 256 bit AES encryption with
Galois Counter Mode (GCM).
@@ -46,19 +49,22 @@ The provided salt should be in hex-encoded String form, be random, and be at lea
Such a salt may be generated 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
----
====
======
Users may 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
@@ -70,19 +76,22 @@ For a more secure alternative, users should prefer `Encryptors.stronger`.
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 the database.
@@ -90,19 +99,22 @@ Encrypted results are returned as hex-encoded strings for easy storage on the fi
Use the Encryptors.queryableText factory method to construct a "queryable" TextEncryptor:
.Queryable TextEncryptor
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
Encryptors.queryableText("password", "salt");
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
Encryptors.queryableText("password", "salt")
----
====
======
The difference between a queryable TextEncryptor and a standard TextEncryptor has to do with initialization vector (iv) handling.
The iv used in a queryable TextEncryptor#encrypt operation is shared, or constant, and is not randomly generated.
@@ -121,74 +133,86 @@ KeyGenerators are thread-safe.
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.
There is also a KeyGenerators.secureRandom variant that 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
Use the KeyGenerators.string factory method to construct a 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
@@ -219,8 +243,10 @@ The default value is 10.
You can change this value in your deployed system without affecting existing passwords, as the value is also stored in the encoded hash.
.BCryptPasswordEncoder
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
@@ -230,7 +256,8 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
@@ -239,15 +266,17 @@ 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.
In order 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.
.Pbkdf2PasswordEncoder
====
.Java
[tabs]
======
Java::
+
[source,java,role="primary"]
----
// Create an encoder with all the defaults
@@ -256,7 +285,8 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
----
.Kotlin
Kotlin::
+
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
@@ -264,4 +294,4 @@ val encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====
======