Spring Security 加密模块

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

加密器

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

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

BytesEncryptor

您可以使用Encryptors.stronger工厂方法来构建一个BytesEncryptor

BytesEncryptor
  • Java

  • Kotlin

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

stronger加密方法通过使用256位AES加密与Galois Counter Mode (GCM)来创建一个加密器。它使用PKCS #5的PBKDF2(基于密码的密钥派生函数#2)来派生密钥。此方法需要Java 6。用于生成SecretKey的密码应保存在安全的地方,并且不应共享。盐用于防止在您的加密数据被泄露的情况下对密钥进行字典攻击。还应用了16字节的随机初始化向量,以确保每个加密消息都是唯一的。

提供的盐应为十六进制编码的字符串形式,应为随机的,并且长度至少为8字节。您可以使用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加密方法,它是256位AES在Cipher Block Chaining (CBC)模式下。此模式不是经过身份验证的,并且不提供有关数据真实性的任何保证。为了获得更安全的替代方案,请使用Encryptors.stronger

TextEncryptor

您可以使用Encryptors.text工厂方法来构建一个标准的TextEncryptor

TextEncryptor
  • Java

  • Kotlin

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

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

密钥生成器

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

BytesKeyGenerator

您可以使用KeyGenerators.secureRandom工厂方法来生成一个由SecureRandom实例支持的BytesKeyGenerator

BytesKeyGenerator
  • Java

  • Kotlin

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

默认密钥长度为8字节。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()

密码编码

spring-security-crypto 模块的密码包提供对密码编码的支持。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))