Spring Security Crypto Module

Spring Security Crypto 模块为对称加密、密钥生成和密码编码提供支持。此代码作为核心模块的一部分进行分发,但没有依赖于任何其他 Spring Security(或 Spring)代码。

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] 实例,以加密文本字符串。加密器是线程安全的。

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

BytesEncryptor

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

BytesEncryptor
  • Java

  • Kotlin

Encryptors.stronger("password", "salt");
Encryptors.stronger("password", "salt")

stronger 加密方法使用 256 位 AES 加密配合加洛瓦计数器模式 (GCM) 创建加密器。它使用 PKCS #5 的 PBKDF2(基于密码的关键派生函数 #2)衍生密钥。此方法需要 Java 6。用于生成 SecretKey 的密码应保存在安全的地方,不应共享。如果你的加密数据泄露,则盐用于防止针对密钥的字典攻击。还应用了 16 字节随机初始化向量,以便每条加密消息都是唯一的。

提供的盐应为十六进制编码的字符串形式,应为随机字符串,并且长度应至少为 8 个字节。你可以使用 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

TextEncryptor

你可以使用 Encryptors.text 工厂方法来构造标准 TextEncryptor:

TextEncryptor
  • Java

  • Kotlin

Encryptors.text("password", "salt");
Encryptors.text("password", "salt")

A TextEncryptor 在加密文本数据时使用了一个标准 BytesEncryptor。加密结果会返回一个十六进制编码字符串,方便存在文件系统或数据库中。

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`是一个线程安全类。

BytesKeyGenerator

可以使用 KeyGenerators.secureRandom 工厂方法来生成 BytesKeyGenerator(由 SecureRandom 实例支持):

BytesKeyGenerator
  • Java

  • Kotlin

BytesKeyGenerator generator = KeyGenerators.secureRandom();
byte[] key = generator.generateKey();
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()

默认密钥长度为 8 字节。A KeyGenerators.secureRandom 变量可以控制密钥长度:

KeyGenerators.secureRandom
  • Java

  • Kotlin

KeyGenerators.secureRandom(16);
KeyGenerators.secureRandom(16)

使用 KeyGenerators.shared 工厂方法构建一个 BytesKeyGenerator,每次调用时始终返回相同的密钥:

KeyGenerators.shared
  • Java

  • Kotlin

KeyGenerators.shared(16);
KeyGenerators.shared(16)

StringKeyGenerator

可以使用 KeyGenerators.string 工厂方法构建一个 8 字节的 SecureRandom KeyGenerator,它将每个密钥作为 String 进行十六进制编码:

StringKeyGenerator
  • Java

  • Kotlin

KeyGenerators.string();
KeyGenerators.string()

Password Encoding

spring-security-crypto 模块的 password 包提供对编码密码的支持。PasswordEncoder 是中心服务接口,具有以下签名:

public interface PasswordEncoder {
	String encode(CharSequence rawPassword);

	boolean matches(CharSequence rawPassword, String encodedPassword);

	default boolean upgradeEncoding(String encodedPassword) {
		return false;
	}
}

如果 rawPassword 在编码后等于 encodedPassword,则 matches 方法返回 true。该方法旨在支持基于密码的身份验证方案。

BCryptPasswordEncoder 实现使用广泛支持的 “bcrypt” 算法对密码进行哈希处理。Bcrypt 会使用一个随机 16 字节的盐值,并故意使用一种慢算法来阻止密码破解。可以使用 strength 参数(其值在 4 到 31 之间)调整其处理量。值越高,计算哈希时需要处理的数据越多。默认值为 10。可以在已部署的系统中更改此值,而不会影响现有密码,因为该值也存储在编码哈希中。以下示例使用了 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

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