# 7.14 SSL

Spring Boot 提供了配置 SSL 信任材料的能力，该材料可应用于多种类型的连接以支持安全通信。带有 `spring.ssl.bundle` 前缀的配置属性可用于指定信任材料和关联信息的命名集。

**7.14.1. 使用 Java KeyStore 文件配置 SSL**

带有`spring.ssl.bundle.jks`前缀的配置属性可用于配置使用 Java`keytool`实用程序创建并以 JKS 或 PKCS12 格式存储在 Java KeyStore 文件中的信任材料包。每个捆绑包都有一个用户提供的名称，可用于引用该捆绑包。

当用于保护嵌入式 Web 服务器时，`keystore`通常配置一个包含证书和私钥的 Java KeyStore，如下例所示：

```
spring.ssl.bundle.jks.mybundle.key.alias=application
spring.ssl.bundle.jks.mybundle.keystore.location=classpath:application.p12
spring.ssl.bundle.jks.mybundle.keystore.password=secret
spring.ssl.bundle.jks.mybundle.keystore.type=PKCS12
```

当用于保护客户端连接时，`truststore`通常使用包含服务器证书的 Java KeyStore 进行配置，如下例所示：

```
spring.ssl.bundle.jks.mybundle.truststore.location=classpath:server.p12
spring.ssl.bundle.jks.mybundle.truststore.password=secret
```

有关完整支持的属性集，请参阅[JksSslBundleProperties 。](https://github.com/spring-projects/spring-boot/tree/v3.2.0/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/JksSslBundleProperties.java)

**7.14.2. 使用 PEM 编码的证书配置 SSL**

带有`spring.ssl.bundle.pem`前缀的配置属性可用于以 PEM 编码文本的形式配置信任材料包。每个捆绑包都有一个用户提供的名称，可用于引用该捆绑包。

当用于保护嵌入式 Web 服务器时，`keystore`通常会配置证书和私钥，如下例所示：

```
spring.ssl.bundle.pem.mybundle.keystore.certificate=classpath:application.crt
spring.ssl.bundle.pem.mybundle.keystore.private-key=classpath:application.key
```

当用于保护客户端连接时，`truststore`通常使用服务器证书进行配置，如下例所示：

```
spring.ssl.bundle.pem.mybundle.truststore.certificate=classpath:server.crt
```

PEM 内容可直接用于`certificate`和`private-key`属性。如果属性值包含`BEGIN`和`END`标记，那么它们将被视为 PEM 内容而不是资源位置。以下示例显示如何定义信任库证书：

```
spring.ssl.bundle.pem.mybundle.truststore.certificate=\
-----BEGIN CERTIFICATE-----\n\
MIID1zCCAr+gAwIBAgIUNM5QQv8IzVQsgSmmdPQNaqyzWs4wDQYJKoZIhvcNAQEL\n\
BQAwezELMAkGA1UEBhMCWFgxEjAQBgNVBAgMCVN0YXRlTmFtZTERMA8GA1UEBwwI\n\
...\n\
V0IJjcmYjEZbTvpjFKznvaFiOUv+8L7jHQ1/Yf+9c3C8gSjdUfv88m17pqYXd+Ds\n\
HEmfmNNjht130UyjNCITmLVXyy5p35vWmdf95U3uEbJSnNVtXH8qRmN9oK9mUpDb\n\
ngX6JBJI7fw7tXoqWSLHNiBODM88fUlQSho8\n\
-----END CERTIFICATE-----\n
```

有关完整支持的属性集，请参阅[PemSslBundleProperties 。](https://github.com/spring-projects/spring-boot/tree/v3.2.0/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ssl/PemSslBundleProperties.java)

**7.14.3. 应用 SSL 捆绑包**

使用属性进行配置后，可以在配置属性中通过名称引用 SSL 捆绑包，以用于 Spring Boot 自动配置的各种类型的连接。[有关更多信息，请参阅有关嵌入式 Web 服务器](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.webserver.configure-ssl)、[数据技术](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#data)和[REST 客户](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#io.rest-client)端的部分。

**7.14.4. 使用 SSL 捆绑包**

Spring Boot 自动配置一个`SslBundles` 类型的bean ，该 bean 提供对使用`spring.ssl.bundle`属性配置的每个命名包的访问。

`SslBundle`可以从自动配置的`SslBundles`bean 中检索并用于创建用于在客户端库中配置 SSL 连接的对象。`SslBundle`提供了获取这些 SSL 对象的分层方法：

* `getStores()`提供对密钥存储和信任存储`java.security.KeyStore`实例以及任何所需的密钥存储密码的访问。
* `getManagers()`提供对`java.net.ssl.KeyManagerFactory`和`java.net.ssl.TrustManagerFactory`实例以及它们创建的`java.net.ssl.KeyManager`和`java.net.ssl.TrustManager`数组的访问。
* `createSslContext()`提供了一种获取新`java.net.ssl.SSLContext`实例的便捷方法。

此外，`SslBundle`还提供了有关正在使用的密钥、要使用的协议以及应应用于 SSL 引擎的任何选项的详细信息。

以下示例展示了检索 `SslBundle`并使用它创建 `SSLContext`：

```
@Component
public class MyComponent {
​
    public MyComponent(SslBundles sslBundles) {
        SslBundle sslBundle = sslBundles.getBundle("mybundle");
        SSLContext sslContext = sslBundle.createSslContext();
        // do something with the created sslContext
    }
​
}
```

**7.14.5. 重新加载 SSL 捆绑包**

当密钥材料发生变化时，可以重新加载 SSL 捆绑包。使用该捆绑包的组件必须与可重新加载的 SSL 捆绑包兼容。目前以下组件兼容：

* Tomcat 网络服务器
* Netty网络服务器

要启用重新加载，您需要通过配置属性选择加入，如本示例所示：

```
spring.ssl.bundle.pem.mybundle.reload-on-update=true
spring.ssl.bundle.pem.mybundle.keystore.certificate=file:/some/directory/application.crt
spring.ssl.bundle.pem.mybundle.keystore.private-key=file:/some/directory/application.key
```

然后，文件监视程序会监视文件，如果文件发生更改，SSL 捆绑包将被重新加载。这反过来会触发使用组件中的重新加载，例如 Tomcat 在启用 SSL 的连接器中轮换证书。

您可以使用`spring.ssl.bundle.watch.file.quiet-period`属性配置文件监视程序的安静期（以确保不再发生更改）。
