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.

BytesEncryptorTextEncryptor 都是接口。BytesEncryptor 有多个实现。

Both BytesEncryptor and TextEncryptor are interfaces. BytesEncryptor has multiple implementations.

BytesEncryptor

你可以使用 Encryptors.stronger 工厂方法来构造 BytesEncryptor

You can use the Encryptors.stronger factory method to construct a BytesEncryptor:

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:

Generating a key
  • 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:

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:

BytesKeyGenerator
  • 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:

KeyGenerators.secureRandom
  • 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:

KeyGenerators.shared
  • 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:

StringKeyGenerator
  • 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:

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:

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))