TLS/SSL
在此页面上
默认情况下,驱动程序使用 JDK 提供的 TLS/SSL 底层支持来支持与 MongoDB 服务器的 TLS/SSL 连接。 可以通过利用 Java SE API 的可扩展性来更改此设置 ,或使用 Netty API。
MongoClient API
您可以通过在 ConnectionString
或MongoClientSettings
实例中指定选项,将驱动程序配置为使用 TLS/SSL。
在 ConnectionString 中指定 TLS/SSL
包括以下 import 语句:
import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClient;
要在 ConnectionString
中指定 TLS/SSL,请将 ssl=true
指定为连接string的一部分:
MongoClient mongoClient = MongoClients.create("mongodb://localhost/?ssl=true");
在 MongoClientSettings 中指定 TLS/SSL
包括以下 import 语句:
import com.mongodb.MongoClientSettings; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClient;
要在MongoClientSettings
实例中指定 TLS/SSL,请将enabled
属性设置为true
:
MongoClientSettings settings = MongoClientSettings.builder() .applyToSslSettings(builder -> builder.enabled(true)) .build(); MongoClient client = MongoClients.create(settings);
在 MongoClientSettings 中指定 Java SE SSLContext
包括以下 import 语句:
import javax.net.ssl.SSLContext; import com.mongodb.MongoClientSettings; import com.mongodb.MongoClient;
要将javax.net.ssl.SSLContext
指定为MongoClientSettings
,请设置sslContext
属性:
SSLContext sslContext = ... MongoClientSettings settings = MongoClientSettings.builder() .applyToSslSettings(builder -> builder.enabled(true).context(sslContext)) .build(); MongoClient client = new MongoClient(settings);
通过 Netty SslContext 自定义 TLS/SSL 配置
包括以下 import 语句:
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 文档。
禁用主机名验证
默认情况下,驱动程序确保服务器的 SSL 证书中包含的主机名与构造MongoClient
时提供的主机名匹配。
如果您的应用程序需要禁用主机名验证,则必须在MongoClientSettings
中明确指示:
MongoClientSettings settings = MongoClientSettings.builder() .applyToSslSettings(builder -> { builder.enabled(true); builder.invalidHostNameAllowed(true); }) .build();
常见 TLS/SSL 配置任务
本节基于 Oracle JDK 的文档 ,因此某些部分可能不适用于您的 JDK 或您使用的自定义 TLS/SSL 实现。
配置信任存储和密钥存储
您可以使用javax.net.ssl.SSLContext.init(KeyManager[] km,
TrustManager[] tm, SecureRandom random)
配置特定于客户端的信任存储和密钥存储,也可以设置 JVM 默认值。
设置默认信任存储
典型的应用程序需要设置多个 JVM 系统属性,以确保客户端可以验证服务器提供的 TLS/SSL 证书:
javax.net.ssl.trustStore
:包含签名机构证书的信任存储区的路径javax.net.ssl.trustStorePassword
:用于访问此信任存储区的密码
信任存储区通常使用作为 JDK 的一部分提供的keytool
命令行程序创建:
keytool -importcert -trustcacerts -file <path to certificate authority file> -keystore <path to trust store> -storepass <trust store password>
设置默认密钥存储
典型的应用程序还需要设置多个 JVM 系统属性,以确保客户端向 MongoDB 服务器提供TLS/SSL 客户端证书:
javax.net.ssl.keyStore
:包含客户端 TLS/SSL 证书的密钥存储区的路径javax.net.ssl.keyStorePassword
:访问此密钥存储区的密码
密钥存储通常使用keytool
或openssl
命令行程序创建。 例如,如果您有一个包含客户端证书及其私钥的文件,并且想要在 PKCS #12 格式,您可以运行以下命令:
openssl pkcs12 -export -in <path to client certificate & private key file> -out <path to key store> -passout pass:<trust store password>
要了解有关为 TLS/SSL 配置 Java 应用程序的更多信息,请参阅 JSSE 参考指南。
强制 TLS v 1.2
某些应用程序可能只想强制使用 TLS 1.2协议。 为此,请将jdk.tls.client.protocols
系统属性设置为TLSv1.2
。
Java 8开始之前的 Java 运行时环境仅在以后的更新中启用 TLS 1.2协议,如上一节所示。 为了使驱动程序在 Java 8之前强制 Java 运行时环境使用 TLS 1.2协议,请确保更新已启用 TLS 1.2 。
OCSP
注意
驱动程序无法在单个MongoClient
的基础上默认启用 OCSP。
客户端驱动的 OCSP
应用程序需要设置以下 JVM 系统和安全属性,以确保启用客户端驱动的 OCSP:
com.sun.net.ssl.checkRevocation
:设置为true
时,此系统属性启用撤销检查ocsp.enable
:当设置为true
时,此安全属性启用客户端驱动的 OCSP
要将应用程序配置为使用客户端驱动的 OCSP,必须已将应用程序设置为使用 TLS 连接到服务器。 要启用客户端驱动的 OCSP,需要设置这些系统属性。
注意
在 OCSP 响应程序不可用的情况下,JDK 提供的 TLS 支持会利用“硬故障”行为,而mongosh
和驱动程序会利用“软故障”行为。
OCSP 装订 (Stapling)
重要
在使用 TLS 1.3协议(Java 11和更高版本默认使用 TLS 1.3 )的 Java 运行时环境中使用 OCSP 装订时,可能会出现以下异常:
javax.net.ssl.SSLHandshakeException: extension (5) should not be presented in certificate_request
该异常是由于 Java 11及更高版本中的 TLS 1.3的一个已知问题造成的。 为了在使用按 TLS 1.3协议运行的 Java 运行时环境时避免出现此异常,您可以强制应用程序使用 TLS 1.2协议。 为此,请将jdk.tls.client.protocols
系统属性设置为TLSv1.2
。
应用程序需要设置多个 JVM 系统属性来设置 OCSP 装订:
jdk.tls.client.enableStatusRequestExtension
:设置为true
(默认值)时,将启用 OCSP 装订。com.sun.net.ssl.checkRevocation
:设置为true
时,将启用撤销检查。 如果此属性未设置为true
,则无论吊销信息是否存在或状态如何,都允许继续连接。
要将应用程序配置为使用 OCSP 装订,必须已将应用程序设置为使用 TLS 连接到服务器,并且必须将服务器设置为将 OCSP 响应装订到它作为 TLS 握手的一部分返回的证书。
要了解有关配置 Java 应用程序以使用 OCSP 的更多信息,请参阅 客户端驱动的 OCSP 和 OCSP 装订 在 Java 文档中。