mongodb 服务器上的 SSLHandshakeFailed 尝试通过 java 驱动程序连接时

相对优质

我一直在尝试通过 java 驱动程序连接一个带有 TLS 1.2 的 mongodb 服务器,但是握手失败,我不明白为什么。这是我的设置

  • MongoDB 服务器 4.2.1
  • mongod.conf:
net:
   bindIp: 127.0.0.1
   port: 27017

   tls:
    mode: requireTLS
    CAFile: <location-to-ca.crt>
    certificateKeyFile: <location-to-server.pem>
    disabledProtocols: TLS1_0,TLS1_1
  • JDK:1.8.0_202
  • mongo-java 驱动程序:3.12.3
private static void Tls1_2Test() throws Exception {
    SSLContext sslContext = createSSLContext();
    MongoClientSettings settings = MongoClientSettings.builder()
            .applyToSslSettings(builder -> {
                builder.enabled(true);
                builder.context(sslContext);
                builder.invalidHostNameAllowed(true);
            })
            .build();
    try (MongoClient client = MongoClients.create(settings)) {
        for (String s : client.listDatabaseNames()) {
            System.out.println(s);
        }
    }
    catch (Exception e) {
        e.printStackTrace();
    }
}

public static SSLContext createSSLContext() throws Exception {

    // root CA
    TrustManagerFactory tmf;
    try (InputStream is = new FileInputStream("<location-to-ca.crt>")) {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(is);
        tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null); // You don't need the KeyStore instance to come from a file.
        ks.setCertificateEntry("caCert", caCert);
        tmf.init(ks);
    }

    // client key
    KeyManagerFactory keyFac;
    try (InputStream is = Test.class.getResourceAsStream("<location-to-client.pem>")) {
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(is, null);
        keyFac = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyFac.init(keystore, null);
    }

    SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
    sslContext.init(keyFac.getKeyManagers(), tmf.getTrustManagers(), null);

    return sslContext;
}

如果我不使用 CAFile 或allowConnectionsWithoutCertificates: true在配置中使用,我可以连接,因为服务器不负责握手的可信权限。但是,我找不到 java 代码有什么问题,因此服务器无法获得用于握手的 CA 证书。

请注意,mongod 配置中的 net.tls.CAFile 和 Java 代码中的根 CA 指向同一文件。我也尝试在 net.tls.CAFile 中使用 .pem 文件,但得到了相同的结果。

这是我尝试连接时的 java 控制台:

14:39:55.501 [main] INFO org.mongodb.driver.cluster - Cluster created with settings {hosts=[127.0.0.1:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
14:39:55.524 [main] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING}]
14:39:55.536 [main] INFO org.mongodb.driver.cluster - Cluster description not yet available. Waiting for 30000 ms before timing out
14:39:55.641 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:1}
14:39:55.643 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] INFO org.mongodb.driver.cluster - Exception in monitor thread while connecting to server 127.0.0.1:27017
com.mongodb.MongoSocketReadException: Exception receiving message
    at com.mongodb.internal.connection.InternalStreamConnection.translateReadException(InternalStreamConnection.java:569)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:448)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:299)
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:259)
    at com.mongodb.internal.connection.CommandHelper.sendAndReceive(CommandHelper.java:83)
    at com.mongodb.internal.connection.CommandHelper.executeCommand(CommandHelper.java:33)
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initializeConnectionDescription(InternalStreamConnectionInitializer.java:105)
    at com.mongodb.internal.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:62)
    at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:129)
    at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
    at sun.security.ssl.InputRecord.read(InputRecord.java:503)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933)
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
    at com.mongodb.internal.connection.SocketStream.read(SocketStream.java:109)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:580)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:445)
    ... 9 common frames omitted
14:39:55.644 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:56.174 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:2}
14:39:56.174 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:56.699 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:3}
14:39:56.700 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]
14:39:57.228 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.connection - Closing connection connectionId{localValue:4}
14:39:57.228 [cluster-ClusterId{value='5e98521b6091fb316cd91fbe', description='null'}-127.0.0.1:27017] DEBUG org.mongodb.driver.cluster - Updating cluster description to  {type=UNKNOWN, servers=[{address=127.0.0.1:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketReadException: Exception receiving message}, caused by {java.net.SocketException: Connection reset}}]

Process finished with exit code 130 (interrupted by signal 2: SIGINT)

这是我尝试连接时服务器的日志:

2020-04-16T14:39:57.227+0200 I  NETWORK  [conn4] Error receiving request from client: SSLHandshakeFailed: SSL peer certificate validation failed: no SSL certificate provided by peer: No error.; connection rejected. Ending connection from 127.0.0.1:52955 (connection id: 4)

提前致谢

相对优质

经过一番挖掘,我发现不能仅仅使用Keystore(因为我没有设置任何Keystore来使用)我使用了充气城堡来读取客户端文件。使用 bouncycastle 1.65 版本。这是我实现它的方法:

我将客户端文件读取更新为以下内容

// client key
KeyManagerFactory keyFac;
try (FileReader fr = new FileReader("<location-to-client.pem>")) {
    KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    keystore.load(null); // needs to be initialised, otherwise throws exception
    PEMParser pemParser = new PEMParser(fr);
    PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) pemParser.readObject();
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
    PrivateKey privateKey = converter.getPrivateKey(privateKeyInfo);
    JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter();
    X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject();
    X509Certificate certificate = certConverter.getCertificate(certificateHolder);
    keystore.setKeyEntry("alias", privateKey, "".toCharArray(), new Certificate[]{certificate});
    keyFac = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    keyFac.init(keystore, "".toCharArray());
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Mongodb连接尝试失败:SSLHandshakeFailed:SSL对等证书验证失败:自签名证书

无法使用Heroku上的Java驱动程序与MongoDB连接

如何防止连接池在mongodb上使用Java驱动程序关闭?

尝试使用MongoDB Java驱动程序更新文档

尝试连接到Azure SQL服务器时,我得到PDOException找不到驱动程序

通过mongoDB Java驱动程序获取mongoStat

MongoDb:通过Java驱动程序在$ external中创建用户

尝试使用Java驱动程序连接到Cassandra时出现AuthenticationException

MongoDB C#2.0驱动程序-如何计算服务器上的聚合计数?

使用 Selenium、IEDriverServer 通过 Java 执行测试时出现“IE 驱动程序的命令行服务器已停止工作”错误

尝试将数据从Spring应用程序发送到远程服务器上的mongodb时出错

Java mongodb连接到远程服务器

如果通过SSH连接到它的PC关闭,则远程服务器上的Java进程终止

如何通过 swi prolog 连接到 MongoDB 服务器?

通过节点服务器连接到MongoDB的警告

通过 Mongoose (nodejs) 从远程服务器连接到 MongoDB

MongoDB Java驱动程序:MongoCore驱动程序与MongoDB驱动程序与MongoDB异步驱动程序

从Java调用mongodb上的服务器js函数

MongoDB .net驱动程序-获取MongoDB服务器版本

MongoDB Java驱动程序-对象类型

MongoDB Java驱动程序记录查询

关于MongoDB Java驱动程序的困惑

MongoDB Java驱动程序:autoConnectRetry

MongoDB Java驱动程序中的死锁

mongodb java驱动程序-原始命令?

MongoDB:使用Java驱动程序拉

MongoDB Java驱动程序-日期查询

MongoDB Java错误驱动程序

MongoDB异步Java驱动程序find()