Docs 菜单

Docs 主页开发应用程序MongoDB 驱动程序Java (Sync) 驱动程序

在连接上启用 TLS/SSL

在此页面上

  • 概述
  • 启用 TLS/SSL
  • 配置证书
  • 配置 JVM 信任存储区
  • 配置 JVM 密钥存储库
  • 配置特定于客户端的信任存储和密钥存储
  • 禁用主机名验证
  • 将连接限制为仅使用 TLS 1.2
  • 通过 Java SE SSLContext 自定义 TLS/SSL 配置
  • 通过 Netty SslContext 自定义 TLS/SSL 配置
  • 在线证书状态协议 (OCSP)
  • 客户端驱动的 OCSP
  • OCSP 装订 (Stapling)

在本指南中,您可以了解如何使用 TLS/SSL 连接到 MongoDB 实例 使用 JDK 中底层 TLS/SSL 支持的安全协议。要将连接配置为使用 TLS/SSL,请在 ConnectionString MongoClientSettings。

注意

调试 TLS/SSL

如果您在设置 TLS/SSL 连接时遇到问题,可以使用-Djavax.net.debug=all 系统属性来查看更多日志语句。请参阅 Oracle TLS/SSL 连接调试指南 以了解更多信息。

您可以通过两种不同的方式为 MongoDB 实例的连接启用 TLS/SSL:通过连接字符串中的参数,或使用 MongoClientSettings.Builder 类中的方法。

注意

如果您使用 DNS 种子列表协议(由连接字符串中的 mongodb+srv 前缀表示)进行连接,则驱动程序会启用 TLS/SSL。要禁用 TLS/SSL,请在连接字符串或 MongoClientSettings 实例中将 tlsssl 参数值设为 false

要了解有关使用 DNS 种子列表时的连接行为的更多信息,请参阅服务器手册中的SRV 连接格式部分。

启动 TLS/SSL 请求的 Java 应用程序需要访问加密证书,这些证书证明应用程序本身以及与应用程序交互的其他应用程序的身份。您可以通过以下机制,在应用程序中配置这些证书的访问权限:

  • JVM 信任存储区与 JVM 密钥存储区

  • 特定于客户端的信任存储和密钥存储

注意

以下各节基于 Oracle JDK 的文档,因此某些内容可能不适用于您的 JDK 或自定义 TLS/SSL 实施。

注意

默认情况下,JRE 包含来自 Let's Encrypt 等签名机构的许多常用公共证书 。因此,您可以使用 TLS/SSL 连接到 MongoDB Atlas 实例(或其证书由 JRE 默认证书存储中的颁发机构签名的任何其他服务器),而无需配置信任存储。

JVM 信任存储所保存的证书可以安全地识别与您的 Java 应用程序交互的其他应用程序。使用这些证书,您的应用程序可以证明与另一应用程序的连接是真实、安全的,不会被第三方篡改。

如果 MongoDB 实例使用的证书由没有位于 JRE 默认证书存储中的颁发机构进行签名,您的应用程序必须配置两个系统属性以启动 SSL/TLS 请求。这些属性确保应用程序可以验证连接的 MongoDB 实例提供的 TLS/SSL 证书。

  • javax.net.ssl.trustStore:包含签名机构证书的信任存储区的路径

  • javax.net.ssl.trustStorePassword:用于访问以下项中定义的信任库的密码: javax.net.ssl.trustStore

您可以使用 keytool 创建信任存储 作为 JDK 的一部分提供的命令行工具:

keytool -importcert -trustcacerts -file <path to certificate authority file>
-keystore <path to trust store> -storepass <password>

注意

默认情况下,MongoDB 实例不执行客户端证书验证。如果将 MongoDB 实例配置为验证客户端证书,您必须配置密钥存储。

JVM 密钥存储区可保存证书,用于向其他应用程序安全地标识 Java 应用程序。使用这些证书,其他应用程序可以证明与您的应用程序的连接是真实的,并且是安全的,不会被第三方篡改。

发起 TLS/SSL 请求的应用程序需要设置两个 JVM 系统属性,以确保客户端向 MongoDB 部署提供 TLS/SSL 证书:

  • javax.net.ssl.keyStore:包含客户端 TLS/SSL 证书的密钥存储区的路径

  • javax.net.ssl.keyStorePassword:用于访问以下项中定义的密钥库的密码: javax.net.ssl.keyStore

您可以使用 keytool 创建密钥存储 或 openssl 命令行工具。

有关配置 Java 应用程序以使用 TLS/SSL 的更多信息,请参阅 JSSE 参考指南。

您可以使用 SSLContext 类的 init() 方法配置客户端对应的信任存储区和密钥存储区。

您可以在本指南的使用 SSLContext 自定义 TLS/SSL 配置部分中找到演示如何使用SSLContext实例配置客户端的示例。

有关SSLContext 类的更多信息,请参阅 SSL 上下文的 API 文档。

默认情况下,驱动程序确保服务器的 TLS/SSL 证书中包含的主机名与构建 MongoClient 时提供的主机名匹配。要为应用程序禁用主机名验证,您可以在 applytoSslSettings() 构建器 Lambda 中将构建器的 invalidHostNameAllowed 属性设置为 true 以明确禁用该功能:

MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(builder -> {
builder.enabled(true);
builder.invalidHostNameAllowed(true);
})
.build();

警告

禁用主机名验证可能会使配置 不安全 。仅出于测试目的或在没有其他选择时禁用主机名验证。

要将应用程序限制为仅使用 TLS 1.2 协议,请将 jdk.tls.client.protocols 系统属性设置为“TLSv1.2”。

注意

Java 8 之前的 Java 运行时环境 (JRE) 仅在更新版本中启用了 TLS 1.2 协议。如果您的 JRE 未启用 TLS 1.2 协议,请升级到更高版本以使用 TLS 1.2 进行连接。

如果您的 TLS/SSL 配置需要自定义,您可以设置 的sslContext 属性,方法是传递MongoClient SSLContext 对象传递给applyToSslSettings() lambda 中的构建者:

SSLContext sslContext = ...
MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(builder -> {
builder.enabled(true);
builder.context(sslContext);
})
.build();
MongoClient client = MongoClients.create(settings);

如果您将驱动程序与 Netty 对于网络 IO,您可以选择插入 Netty 提供的替代 TLS/SSL 协议实现。

import com.mongodb.MongoClientSettings;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoClient;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;

注意

驱动程序使用 Netty 版本进行测试 io.netty:netty-all:4.1.87.Final

指示驱动程序使用 io.netty.handler.ssl.SslContext ,配置 NettyTransportSettings 当您定义 MongoClientSettings 。使用 MongoClientSettings.Builder.transportSettings NettyTransportSettings.Builder.sslContext 构建您的设置:

SslContext sslContext = SslContextBuilder.forClient()
.sslProvider(SslProvider.OPENSSL)
.build();
MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(builder -> builder.enabled(true))
.transportSettings(TransportSettings.nettyBuilder()
.sslContext(sslContext)
.build())
.build();
MongoClient client = MongoClients.create(settings);

有关io.netty.handler.ssl.SslProvider 的更多详细信息,请参阅 Netty 文档

OCSP 是一种用于检查是否已撤销 X.509 证书的标准。证书颁发机构 (CA) 可以在到期时间之前将 X.509 证书添加到证书撤销列表 (CRL) 中,以使该证书失效。当客户端在 TLS 握手期间发送 X.509 证书时,CA 的撤销服务器检查 CRL 并返回“良好”、“已撤销”或“未知”状态。

该驱动程序支持以下 OCSP 变体:

  • 客户端驱动的 OCSP

  • OCSP 装订 (Stapling)

以下部分描述了变体之间的差异以及如何为您的应用程序启用这些变体。

注意

Java 驱动程序使用为应用程序配置的 JVM 参数,并且无法针对特定的 MongoClient 实例进行重写。

在客户端驱动的 OCSP 中,客户端在收到服务器发送的证书后,将 OCSP 请求中的证书发送给 OCSP 响应程序。OCSP 响应程序通过证书颁发机构 (CA) 检查证书的状态,并在发送给客户端的响应中报告证书是否有效。

要为您的应用程序启用客户端驱动的 OCSP,请设置以下 JVM 系统属性:

属性
com.sun.net.ssl.checkRevocation
将此属性设置为 true 以启用撤销检查。
ocsp.enable
将此属性设置为true以启用客户端驱动的 OCSP。

警告

如果 OCSP 响应程序不可用,JDK 提供的 TLS 支持会报告“硬故障”。这与 MongoDB Shell 和其他一些驱动程序的“软故障”行为不同。

OCSP 装订是一种机制,在该机制中,服务器必须从证书颁发机构 (CA) 获取签名证书,并将其包含在对客户端的带时间戳的 OCSP 响应中。

要为您的应用程序启用 OCSP 装订,请设置以下 JVM 系统属性:

属性
说明
com.sun.net.ssl.checkRevocation
将此属性设置为 true 以启用撤销检查。
jdk.tls.client.enableStatusRequestExtension
将此属性设置为 true 以启用 OCSP 装订。

如果未设置或设置为 false ,则无论证书吊销响应是否存在或状态如何,该连接都可继续进行。

有关 OCSP 的更多信息,请查看以下资源:

← 网络压缩