# Spring 安全加密模块

## 导言

Spring 安全加密模块提供对对称加密、密钥生成和密码编码的支持。该代码作为核心模块的一部分进行分发，但不依赖于任何其他 Spring 安全性（或 Spring）代码。

## 加密者

Encryptors 类提供了用于构造对称加密器的工厂方法。使用这个类，你可以创建 ByteenCryptors 来加密原始字节[]形式的数据。你还可以构造文本加密器来加密文本字符串。加密器是线程安全的。

### BytesenCryptor

使用`Encryptors.stronger`工厂方法来构造一个 ByteSenCryptor:

例 1。BytesenCryptor

爪哇

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

Kotlin

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

“更强”的加密方法使用 256 位 AES 加密和伽罗瓦计数器模式创建一个加密器。它使用 PKCS#5 的 PBKDF2（基于密码的密钥派生函数 #2）来派生密钥。这个方法需要 爪哇6。用于生成秘密密钥的密码应保存在安全的地方，不得共享。SALT 用于防止在你的加密数据遭到破坏时对密钥发起字典攻击。还应用了 16 字节的随机初始化向量，因此每个加密消息都是唯一的。

所提供的 SALT 应该是十六进制编码的字符串形式，是随机的，并且至少有 8 个字节的长度。可以使用键盘生成器生成这样的 salt:

例 2。生成密钥

爪哇

```
String salt = KeyGenerators.string().generateKey(); // generates a random 8-byte salt that is then hex-encoded
```

Kotlin

```
val salt = KeyGenerators.string().generateKey() // generates a random 8-byte salt that is then hex-encoded
```

用户也可以使用`standard`加密方法，这是在密码块链接模式下的 256 位 AES。此模式不是[已认证](https://en.wikipedia.org/wiki/Authenticated_encryption)，并且不提供有关数据真实性的任何保证。对于更安全的选择，用户应该更喜欢`Encryptors.stronger`。

### TextEncryptor

使用 Encryptors.text Factory 方法构建一个标准的 TextEncryptor:

例 3。TextEncryptor

爪哇

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

Kotlin

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

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

使用 Encryptors.queryableText Factory 方法构造一个“可查询的”文本加密程序：

例 4。可查询文本加密器

爪哇

```
Encryptors.queryableText("password", "salt");
```

Kotlin

```
Encryptors.queryableText("password", "salt")
```

可查询文本加密器和标准文本加密器之间的区别与初始化向量处理有关。在可查询的 TextEncryptor#Encrypt 操作中使用的 IV 是共享的或常量的，并且不是随机生成的。这意味着多次加密的相同文本将始终产生相同的加密结果。这不太安全，但对于需要查询的加密数据来说是必要的。可查询加密文本的一个例子是 OAuth Apikey。

## 关键生成器

keygenerators 类为构造不同类型的密钥生成器提供了许多方便的工厂方法。使用这个类，你可以创建一个 byteskeygenerator 来生成 byte[]键。你还可以构造一个 串键生成器 来生成 String 键。键盘生成器是线程安全的。

### Byteskeygenerator

使用 keygenerators.secureRandom Factory 方法生成由 secureRandom 实例支持的 byteskeygenerator:

例 5。Byteskeygenerator

爪哇

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

Kotlin

```
val generator = KeyGenerators.secureRandom()
val key = generator.generateKey()
```

默认的密钥长度是 8 个字节。还有一个 keygenerators.secureRandom 变体，它提供对密钥长度的控制：

例 6。keygenerators.secureRandom

爪哇

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

Kotlin

```
KeyGenerators.secureRandom(16)
```

使用 keygenerators.shared Factory 方法构造一个 byteskeygenerator，它总是在每次调用时返回相同的键：

例 7。keygenerators.shared

爪哇

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

Kotlin

```
KeyGenerators.shared(16)
```

### StringKeyGenerator

使用 keygenerators.string Factory 方法构造一个 8 字节的安全随机密钥生成器，将每个密钥作为字符串进行十六进制编码：

例 8。串键生成器

爪哇

```
KeyGenerators.string();
```

Kotlin

```
KeyGenerators.string()
```

## 密码编码

Spring-security-crypto 模块的密码包提供了对密码编码的支持。`PasswordEncoder`是中心服务接口，具有以下签名：

```
public interface PasswordEncoder {

String encode(String rawPassword);

boolean matches(String rawPassword, String encodedPassword);
}
```

如果编码后的 RAWPassword 等于 EncodedPassword，则 Matches 方法返回 true。该方法旨在支持基于密码的身份验证方案。

`BCryptPasswordEncoder`实现使用广泛支持的“bcrypt”算法来散列密码。Bcrypt 使用一个随机的 16 字节的盐值，并且是一个故意缓慢的算法，以阻止密码破解器。它所做的工作量可以使用“强度”参数进行调整，该参数的取值范围为 4 到 31。值越高，计算散列所需做的工作就越多。默认值是 10。你可以在部署的系统中更改该值，而不会影响现有的密码，因为该值也存储在编码的散列中。

例 9。bcryptpasswordencoder

爪哇

```
// Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
```

Kotlin

```
// 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 秒来验证你的系统上的密码。

例 10。PBKDF2PASSWORDENCODER

Java

```
// Create an encoder with all the defaults
Pbkdf2PasswordEncoder encoder = new Pbkdf2PasswordEncoder();
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
```

Kotlin

```
// Create an encoder with all the defaults
val encoder = Pbkdf2PasswordEncoder()
val result: String = encoder.encode("myPassword")
assertTrue(encoder.matches("myPassword", result))
```