此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.3.1Spring中文文档

Spring Security Crypto 模块支持对称加密、密钥生成和密码编码。 该代码作为核心模块的一部分分发,但不依赖于任何其他 Spring Security(或 Spring)代码。Spring中文文档

加密程序

Encryptors 类提供用于构造对称加密器的工厂方法。 此类允许您创建 BytesEncryptor 实例以原始形式加密数据。 还可以构造 TextEncryptor 实例来加密文本字符串。 加密器是线程安全的。byte[]Spring中文文档

两者都是接口。 具有多个实现。BytesEncryptorTextEncryptorBytesEncryptorSpring中文文档

BytesEncryptor

您可以使用工厂方法构造一个:Encryptors.strongerBytesEncryptorSpring中文文档

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

加密方法通过使用 256 位 AES 加密和 伽罗瓦计数器模式(GCM)。 它使用 PKCS #5 的 PBKDF2(基于密码的密钥派生函数 #2)派生密钥。 此方法需要 Java 6。 用于生成密码的密码应保存在安全的地方,不应共享。 盐用于防止在加密数据泄露时对密钥进行字典攻击。 还应用了 16 字节的随机初始化向量,以便每个加密消息都是唯一的。strongerSecretKeySpring中文文档

提供的 salt 应采用十六进制编码的 String 形式,是随机的,长度至少为 8 个字节。 您可以使用以下方法生成此类盐:KeyGeneratorSpring中文文档

生成密钥
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

您还可以使用加密方法,即密码块链 (CBC) 模式下的 256 位 AES。 此模式未经身份验证,也不提供任何 保证数据的真实性。 如需更安全的替代方法,请使用 。standardEncryptors.strongerSpring中文文档

TextEncryptor

可以使用工厂方法构造标准 TextEncryptor:Encryptors.textSpring中文文档

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

A 使用标准对文本数据进行加密。 加密结果以十六进制编码字符串的形式返回,以便于存储在文件系统或数据库中。TextEncryptorBytesEncryptorSpring中文文档

两者都是接口。 具有多个实现。BytesEncryptorTextEncryptorBytesEncryptorSpring中文文档

密钥生成器

KeyGenerators 类提供了许多方便的工厂方法,用于构造不同类型的密钥生成器。 通过使用此类,可以创建 BytesKeyGenerator 来生成密钥。 您还可以构造一个 StringKeyGenerator' 来生成字符串键。 是一个线程安全类。byte[]KeyGeneratorsSpring中文文档

BytesKeyGenerator

您可以使用工厂方法生成由实例支持的实例:KeyGenerators.secureRandomBytesKeyGeneratorSecureRandomSpring中文文档

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

默认密钥长度为 8 个字节。 变体提供对密钥长度的控制:KeyGenerators.secureRandomSpring中文文档

密钥生成器.secureRandom
KeyGenerators.secureRandom(16);
KeyGenerators.secureRandom(16)

使用工厂方法构造一个 BytesKeyGenerator,该生成器在每次调用时始终返回相同的键:KeyGenerators.sharedSpring中文文档

KeyGenerators.shared(密钥生成器.shared)
KeyGenerators.shared(16);
KeyGenerators.shared(16)

StringKey生成器

您可以使用工厂方法构造一个 8 字节,将每个密钥十六进制编码为:KeyGenerators.stringSecureRandomKeyGeneratorStringSpring中文文档

StringKey生成器
KeyGenerators.string();
KeyGenerators.string()

密码编码

模块的密码包支持对密码进行编码。 是中央服务接口,具有以下签名:spring-security-cryptoPasswordEncoderSpring中文文档

public interface PasswordEncoder {
	String encode(CharSequence rawPassword);

	boolean matches(CharSequence rawPassword, String encodedPassword);

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

如果 编码后等于 . 此方法旨在支持基于密码的身份验证方案。matchesrawPasswordencodedPasswordSpring中文文档

该实现使用广泛支持的“bcrypt”算法对密码进行哈希处理。 Bcrypt 使用随机的 16 字节盐值,是一种故意放慢速度的算法,以阻止密码破解。 您可以使用参数调整它所做的工作量,该参数采用介于 4 到 31 之间的值。 该值越高,计算哈希值所需的工作就越多。 默认值为 。 您可以在部署的系统中更改此值,而不会影响现有密码,因为该值也存储在编码的哈希中。 以下示例使用 :BCryptPasswordEncoderstrength10BCryptPasswordEncoderSpring中文文档

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

该实现使用 PBKDF2 算法对密码进行哈希处理。 为了破解密码,PBKDF2 是一种故意变慢的算法,应调整为大约需要 5 秒来验证系统上的密码。 以下系统使用 :Pbkdf2PasswordEncoderPbkdf2PasswordEncoderSpring中文文档

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