文档菜单
文档首页
/ / /
Java 同步驱动程序
/ /

在连接上启用 TLS/SSL

本页内容

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

在本指南中,您将学习如何使用以下方式连接到MongoDB实例:TLS/SSL 安全协议,该协议利用JDK底层的TLS/SSL支持。要配置您的连接使用TLS/SSL,请启用ConnectionStringMongoClientSettings. 中的TLS/SSL设置。

注意

调试TLS/SSL

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

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

注意

如果您使用DNS种子列表协议连接,该协议由连接字符串中的mongodb+srv前缀指示,驱动程序会启用TLS/SSL。要禁用它,请将连接字符串中的tlsssl参数值设置为falseMongoClientSettings实例。

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

要在与ConnectionString的连接上启用TLS/SSL,请将传递给MongoClients.create()的连接字符串参数tls设置为true。请参考ConnectionString

MongoClient mongoClient = MongoClients.create("mongodb+srv://<db_username>:<db_password>@<cluster-url>?tls=true");

使用MongoClientSettings.Builder类配置MongoClient的TLS/SSL连接选项,请调用applyToSslSettings()方法。在SslSettings.Builder块中将enabled属性设置为true以启用TLS/SSL

MongoClientSettings settings = MongoClientSettings.builder()
.applyToSslSettings(builder ->
builder.enabled(true))
.build();
MongoClient client = MongoClients.create(settings);

启动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 中定义的信任库的密码

您可以使用JDK提供的命令行工具 keytool 创建一个信任库

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中定义的密钥库的密码

您可以使用keytoolopenssl命令行工具来创建密钥库。

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

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

在指南的“使用SSLContext自定义TLS/SSL配置”部分,您可以找到一个示例,说明如何使用SSLContext实例配置客户端。自定义TLS/SSL配置

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

默认情况下,驱动程序会确保服务器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 运行时环境(JRE)在 Java 8 之前的版本仅在新版更新中启用了 TLS 1.2 协议。如果您的 JRE 未启用 TLS 1.2 协议,请升级到较新版本以使用 TLS 1.2 进行连接。

如果您的TLS/SSL配置需要定制,您可以通过向applyToSslSettings() lambda传递一个SSLContext对象来设置您的MongoClientsslContext属性

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

如果您使用的是与网络IO相关的Netty驱动程序,您可以选择插入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进行了测试

To instruct the driver to use io.netty.handler.ssl.SslContext, configure NettyTransportSettings when you define your MongoClientSettings. Use MongoClientSettings.Builder.transportSettings and NettyTransportSettings.Builder.sslContext to build your settings

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证书是否被撤销的标准。证书颁发机构可以在证书过期之前将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 stapling是一种机制,其中服务器必须从证书权威机构(CA)获取签名证书,并将其包含在带时间戳的OCSP响应中发送给客户端。

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

属性
描述
com.sun.net.ssl.checkRevocation
将此属性设置为true以启用撤消检查。
jdk.tls.client.enableStatusRequestExtension
将此属性设置为true以启用OCSP stapling。

如果未设置或设置为false,则可以在不考虑证书撤回响应的存在或状态的情况下继续连接。

有关OCSP的更多信息,请参阅以下资源

返回

网络压缩