Spring Security Crypto Module
Spring Security Crypto 模块为对称加密、密钥生成和密码编码提供支持。此代码作为核心模块的一部分进行分发,但没有依赖于任何其他 Spring Security(或 Spring)代码。
The Spring Security Crypto module provides support for symmetric encryption, key generation, and password encoding. The code is distributed as part of the core module but has no dependencies on any other Spring Security (or Spring) code.
Encryptors
{security-api-url}org/springframework/security/crypto/encrypt/Encryptors.html[Encryptors
] 类提供了用于构建对称加密器的工厂方法。通过此类,您可以创建 {security-api-url}org/springframework/security/crypto/encrypt/BytesEncryptor.html[BytesEncryptor
] 实例,以以原始 `byte[]`形式加密数据。您还可以构建 {security-api-url}org/springframework/security/crypto/encrypt/TextEncryptor.html[TextEncryptor] 实例,以加密文本字符串。加密器是线程安全的。
The {security-api-url}org/springframework/security/crypto/encrypt/Encryptors.html[Encryptors
] class provides factory methods for constructing symmetric encryptors.
This class lets you create {security-api-url}org/springframework/security/crypto/encrypt/BytesEncryptor.html[BytesEncryptor
] instances to encrypt data in raw byte[]
form.
You can also construct {security-api-url}org/springframework/security/crypto/encrypt/TextEncryptor.html[TextEncryptor] instances to encrypt text strings.
Encryptors are thread-safe.
Both |
BytesEncryptor
你可以使用 Encryptors.stronger
工厂方法来构造 BytesEncryptor
:
You can use the Encryptors.stronger
factory method to construct a BytesEncryptor
:
-
Java
-
Kotlin
Encryptors.stronger("password", "salt");
Encryptors.stronger("password", "salt")
stronger
加密方法使用 256 位 AES 加密配合加洛瓦计数器模式 (GCM) 创建加密器。它使用 PKCS #5 的 PBKDF2(基于密码的关键派生函数 #2)衍生密钥。此方法需要 Java 6。用于生成 SecretKey
的密码应保存在安全的地方,不应共享。如果你的加密数据泄露,则盐用于防止针对密钥的字典攻击。还应用了 16 字节随机初始化向量,以便每条加密消息都是唯一的。
The stronger
encryption method creates an encryptor by using 256-bit AES encryption with
Galois Counter Mode (GCM).
It derives the secret key by using PKCS #5’s PBKDF2 (Password-Based Key Derivation Function #2).
This method requires Java 6.
The password used to generate the SecretKey
should be kept in a secure place and should not be shared.
The salt is used to prevent dictionary attacks against the key in the event that your encrypted data is compromised.
A 16-byte random initialization vector is also applied so that each encrypted message is unique.
提供的盐应为十六进制编码的字符串形式,应为随机字符串,并且长度应至少为 8 个字节。你可以使用 KeyGenerator
生成此类盐:
The provided salt should be in hex-encoded String form, be random, and be at least 8 bytes in length.
You can generate such a salt by using a KeyGenerator
:
-
Java
-
Kotlin
String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
val salt = KeyGenerators.string().generateKey() // generates a random 8-byte salt that is then hex-encoded
您还可以使用 standard`加密方法,即密码块链接 (CBC) 模式下的 256 位 AES。此模式不 authenticated且不提供对数据真实性的任何担保。要使用更安全的替代方法,请使用 `Encryptors.stronger
。
You can also use the standard
encryption method, which is 256-bit AES in Cipher Block Chaining (CBC) Mode.
This mode is not authenticated and does not provide any
guarantees about the authenticity of the data.
For a more secure alternative, use Encryptors.stronger
.
TextEncryptor
你可以使用 Encryptors.text
工厂方法来构造标准 TextEncryptor:
You can use the Encryptors.text
factory method to construct a standard TextEncryptor:
-
Java
-
Kotlin
Encryptors.text("password", "salt");
Encryptors.text("password", "salt")
A TextEncryptor
在加密文本数据时使用了一个标准 BytesEncryptor
。加密结果会返回一个十六进制编码字符串,方便存在文件系统或数据库中。
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.
Key Generators
{security-api-url}org/springframework/security/crypto/keygen/KeyGenerators.html[KeyGenerators
] 类提供了一些便捷的工厂方法,用于构建不同类型的密钥生成器。通过使用此类,您可以创建一个 {security-api-url}org/springframework/security/crypto/keygen/BytesKeyGenerator.html[BytesKeyGenerator
],以生成 byte[]`密钥。您还可以构建一个 {security-api-url}org/springframework/security/crypto/keygen/StringKeyGenerator.html
[StringKeyGenerator]`,以生成字符串密钥。`KeyGenerators`是一个线程安全类。
The {security-api-url}org/springframework/security/crypto/keygen/KeyGenerators.html[KeyGenerators
] class provides a number of convenience factory methods for constructing different types of key generators.
By using this class, you can create a {security-api-url}org/springframework/security/crypto/keygen/BytesKeyGenerator.html[BytesKeyGenerator
] to generate byte[]
keys.
You can also construct a {security-api-url}org/springframework/security/crypto/keygen/StringKeyGenerator.html`[StringKeyGenerator]` to generate string keys.
KeyGenerators
is a thread-safe class.
BytesKeyGenerator
可以使用 KeyGenerators.secureRandom
工厂方法来生成 BytesKeyGenerator
(由 SecureRandom
实例支持):
You can use the KeyGenerators.secureRandom
factory methods to generate a BytesKeyGenerator
backed by a SecureRandom
instance:
-
Java
-
Kotlin
BytesKeyGenerator generator = KeyGenerators.secureRandom();
byte[] key = generator.generateKey();
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()
默认密钥长度为 8 字节。A KeyGenerators.secureRandom
变量可以控制密钥长度:
The default key length is 8 bytes.
A KeyGenerators.secureRandom
variant provides control over the key length:
-
Java
-
Kotlin
KeyGenerators.secureRandom(16);
KeyGenerators.secureRandom(16)
使用 KeyGenerators.shared
工厂方法构建一个 BytesKeyGenerator,每次调用时始终返回相同的密钥:
Use the KeyGenerators.shared
factory method to construct a BytesKeyGenerator that always returns the same key on every invocation:
-
Java
-
Kotlin
KeyGenerators.shared(16);
KeyGenerators.shared(16)
StringKeyGenerator
可以使用 KeyGenerators.string
工厂方法构建一个 8 字节的 SecureRandom
KeyGenerator
,它将每个密钥作为 String
进行十六进制编码:
You can use the KeyGenerators.string
factory method to construct an 8-byte, SecureRandom
KeyGenerator
that hex-encodes each key as a String
:
-
Java
-
Kotlin
KeyGenerators.string();
KeyGenerators.string()
Password Encoding
spring-security-crypto
模块的 password 包提供对编码密码的支持。PasswordEncoder
是中心服务接口,具有以下签名:
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:
public interface PasswordEncoder {
String encode(CharSequence rawPassword);
boolean matches(CharSequence rawPassword, String encodedPassword);
default boolean upgradeEncoding(String encodedPassword) {
return false;
}
}
如果 rawPassword
在编码后等于 encodedPassword
,则 matches
方法返回 true。该方法旨在支持基于密码的身份验证方案。
The matches
method returns true if the rawPassword
, once encoded, equals the encodedPassword
.
This method is designed to support password-based authentication schemes.
BCryptPasswordEncoder
实现使用广泛支持的 “bcrypt” 算法对密码进行哈希处理。Bcrypt 会使用一个随机 16 字节的盐值,并故意使用一种慢算法来阻止密码破解。可以使用 strength
参数(其值在 4 到 31 之间)调整其处理量。值越高,计算哈希时需要处理的数据越多。默认值为 10
。可以在已部署的系统中更改此值,而不会影响现有密码,因为该值也存储在编码哈希中。以下示例使用了 BCryptPasswordEncoder
:
The BCryptPasswordEncoder
implementation uses the widely supported “bcrypt” algorithm to hash the passwords.
Bcrypt uses a random 16-byte salt value and is a deliberately slow algorithm, to hinder password crackers.
You can tune the amount of work it does by using the strength
parameter, which takes a value from 4 to 31.
The higher the value, the more work has to be done to calculate the hash.
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.
The following example uses the BCryptPasswordEncoder
:
-
Java
-
Kotlin
// Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
// Create an encoder with strength 16
val encoder = BCryptPasswordEncoder(16)
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
Pbkdf2PasswordEncoder
实现使用 PBKDF2 算法对密码进行哈希处理。为了防止密码破解,PBKDF2 采用了一种故意慢的算法,应调整为在您的系统上验证密码大约需要 0.5 秒。以下系统使用了 Pbkdf2PasswordEncoder
:
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.
The following system uses the Pbkdf2PasswordEncoder
:
-
Java
-
Kotlin
// Create an encoder with all the defaults
Pbkdf2PasswordEncoder encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8();
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
// Create an encoder with all the defaults
val encoder = Pbkdf2PasswordEncoder.defaultsForSpringSecurity_v5_8()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))