Add crypto Kotlin samples to docs

Issue gh-8172
This commit is contained in:
Eleftheria Stein 2020-03-30 11:32:43 -04:00
parent 018cbfa93f
commit 63c8072ebc
1 changed files with 118 additions and 12 deletions

View File

@ -19,11 +19,21 @@ Encryptors are thread-safe.
=== BytesEncryptor === BytesEncryptor
Use the `Encryptors.stronger` factory method to construct a BytesEncryptor: Use the `Encryptors.stronger` factory method to construct a BytesEncryptor:
[source,java] .BytesEncryptor
====
.Java
[source,java,role="primary"]
---- ----
Encryptors.stronger("password", "salt"); Encryptors.stronger("password", "salt");
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
Encryptors.stronger("password", "salt")
----
====
The "stronger" encryption method creates an encryptor using 256 bit AES encryption with The "stronger" encryption method creates an encryptor using 256 bit AES encryption with
Galois Counter Mode (GCM). Galois Counter Mode (GCM).
It derives the secret key using PKCS #5's PBKDF2 (Password-Based Key Derivation Function #2). It derives the secret key using PKCS #5's PBKDF2 (Password-Based Key Derivation Function #2).
@ -35,11 +45,21 @@ A 16-byte random initialization vector is also applied so each encrypted message
The provided salt should be in hex-encoded String form, be random, and be at least 8 bytes in length. The provided salt should be in hex-encoded String form, be random, and be at least 8 bytes in length.
Such a salt may be generated using a KeyGenerator: Such a salt may be generated using a KeyGenerator:
[source,java] .Generating a key
====
.Java
[source,java,role="primary"]
---- ----
String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
---- ----
.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. 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 This mode is not https://en.wikipedia.org/wiki/Authenticated_encryption[authenticated] and does not provide any
guarantees about the authenticity of the data. guarantees about the authenticity of the data.
@ -49,22 +69,41 @@ For a more secure alternative, users should prefer `Encryptors.stronger`.
=== TextEncryptor === TextEncryptor
Use the Encryptors.text factory method to construct a standard TextEncryptor: Use the Encryptors.text factory method to construct a standard TextEncryptor:
[source,java] .TextEncryptor
====
.Java
[source,java,role="primary"]
---- ----
Encryptors.text("password", "salt"); Encryptors.text("password", "salt");
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
Encryptors.text("password", "salt")
----
====
A TextEncryptor uses a standard BytesEncryptor to encrypt text data. 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. Encrypted results are returned as hex-encoded strings for easy storage on the filesystem or in the database.
Use the Encryptors.queryableText factory method to construct a "queryable" TextEncryptor: Use the Encryptors.queryableText factory method to construct a "queryable" TextEncryptor:
[source,java] .Queryable TextEncryptor
====
.Java
[source,java,role="primary"]
---- ----
Encryptors.queryableText("password", "salt"); Encryptors.queryableText("password", "salt");
---- ----
.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 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. The iv used in a queryable TextEncryptor#encrypt operation is shared, or constant, and is not randomly generated.
This means the same text encrypted multiple times will always produce the same encryption result. This means the same text encrypted multiple times will always produce the same encryption result.
@ -81,35 +120,76 @@ KeyGenerators are thread-safe.
=== BytesKeyGenerator === BytesKeyGenerator
Use the KeyGenerators.secureRandom factory methods to generate a BytesKeyGenerator backed by a SecureRandom instance: Use the KeyGenerators.secureRandom factory methods to generate a BytesKeyGenerator backed by a SecureRandom instance:
[source,java] .BytesKeyGenerator
====
.Java
[source,java,role="primary"]
---- ----
BytesKeyGenerator generator = KeyGenerators.secureRandom(); BytesKeyGenerator generator = KeyGenerators.secureRandom();
byte[] key = generator.generateKey(); byte[] key = generator.generateKey();
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()
----
====
The default key length is 8 bytes. The default key length is 8 bytes.
There is also a KeyGenerators.secureRandom variant that provides control over the key length: There is also a KeyGenerators.secureRandom variant that provides control over the key length:
[source,java] .KeyGenerators.secureRandom
====
.Java
[source,java,role="primary"]
---- ----
KeyGenerators.secureRandom(16); KeyGenerators.secureRandom(16);
---- ----
.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: Use the KeyGenerators.shared factory method to construct a BytesKeyGenerator that always returns the same key on every invocation:
[source,java] .KeyGenerators.shared
====
.Java
[source,java,role="primary"]
---- ----
KeyGenerators.shared(16); KeyGenerators.shared(16);
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
KeyGenerators.shared(16)
----
====
=== StringKeyGenerator === StringKeyGenerator
Use the KeyGenerators.string factory method to construct a 8-byte, SecureRandom KeyGenerator that hex-encodes each key as a String: Use the KeyGenerators.string factory method to construct a 8-byte, SecureRandom KeyGenerator that hex-encodes each key as a String:
[source,java] .StringKeyGenerator
====
.Java
[source,java,role="primary"]
---- ----
KeyGenerators.string(); KeyGenerators.string();
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
KeyGenerators.string()
----
====
[[spring-security-crypto-passwordencoders]] [[spring-security-crypto-passwordencoders]]
== Password Encoding == Password Encoding
The password package of the spring-security-crypto module provides support for encoding passwords. The password package of the spring-security-crypto module provides support for encoding passwords.
@ -135,7 +215,10 @@ The higher the value, the more work has to be done to calculate the hash.
The default value is 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. You can change this value in your deployed system without affecting existing passwords, as the value is also stored in the encoded hash.
[source,java] .BCryptPasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with strength 16 // Create an encoder with strength 16
@ -144,15 +227,38 @@ String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with strength 16
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. 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. 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.
[source,java] .Pbkdf2PasswordEncoder
====
.Java
[source,java,role="primary"]
---- ----
// Create an encoder with all the defaults // Create an encoder with all the defaults
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder(); Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
String result = encoder.encode("myPassword"); String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result)); assertTrue(encoder.matches("myPassword", result));
---- ----
.Kotlin
[source,kotlin,role="secondary"]
----
// Create an encoder with all the defaults
val encoder = Pbkdf2PasswordEncoder()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
----
====