TLS/SSL
在本页
默认情况下,驱动程序支持通过JDK提供的TLS/SSL底层支持,使用TLS/SSL连接到MongoDB服务器。这可以通过利用Java SE API的扩展性,或者通过使用Netty API。
MongoClient API
您可以通过在ConnectionString
或MongoClientSettings
实例中指定选项来配置驱动程序使用TLS/SSL。
在ConnectionString中指定TLS/SSL
包含以下导入语句
import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoClient;
要在一个ConnectionString
中指定TLS/SSL,请将连接字符串中的ssl=true
指定为TLS/SSL
MongoClient mongoClient = MongoClients.create("mongodb://localhost/?ssl=true");
在MongoClientSettings中指定TLS/SSL
包含以下导入语句
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 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 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,在定义您的 MongoClientSettings
时配置 NettyTransportSettings。
使用 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系统属性,以确保客户端呈现 TLS/SSL客户端证书给MongoDB服务器
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>
要了解更多关于配置Java应用程序使用TLS/SSL的信息,请参阅JSSE参考指南。
强制使用TLS v1.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的必要条件。
注意
JDK提供的TLS支持在OCSP响应者不可用时使用“硬失败”行为,这与使用“软失败”行为的mongosh
和驱动程序不同。
OCSP Stapling
重要
当在使用TLS 1.3协议的Java运行时环境中使用OCSP Stapling时(Java 11及以上版本默认使用TLS 1.3),可能会出现以下异常
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
。
要设置OCSP Stapling,应用程序需要设置多个JVM系统属性
jdk.tls.client.enableStatusRequestExtension
:当设置为true
(其默认值)时,此启用OCSP Stapling。com.sun.net.ssl.checkRevocation
:当设置为true
时,此启用撤销检查。如果此属性未设置为true
,则连接将被允许继续进行,无论撤销信息是否存在或状态如何。
要配置应用程序使用OCSP Stapling,应用程序必须已经配置为使用TLS连接到服务器,并且服务器必须配置为将OCSP响应附加到它作为TLS握手一部分返回的证书。
要了解更多关于配置Java应用程序使用OCSP的信息,请参阅Java文档中的客户端驱动OCSP和OCSP Stapling。