2017-02-17 63 views
2

我有一个MongoDb实例正在运行(单实例),启用了SSL。我能够与RoboMongo连接到它那里SSL选项卡上我提供以下信息:使用SSL从JAVA应用程序连接到MongoDb

CA File : /path to my certificate/testCA.pem 
PEM certificate/key: /path to my key/testKey.pem 

哪些成功连接。现在我试图从java应用程序连接到相同的mondodb。我进口testCA.pem到使用以下命令的cacerts:

keytool -import -keystore cacerts -file testCA.pem -storepass changeit 

,我可以看到添加到存储的新条目。试图添加其他密钥到它,它说无效的证书。在Java应用程序我设置系统属性如下:

System.setProperty ("javax.net.ssl.trustStore","C:\\Program Files\\Java\\jre1.8.0_91\\lib\\security\\cacerts"); 
System.setProperty ("javax.net.ssl.trustStorePassword","changeit"); 

,我发现了以下错误:

org.springframework.dao.DataAccessResourceFailureException: Timed out after 10000 ms while waiting to connect. Client view of cluster state is {type=Unknown, servers=[{address=test.mongo.com:27017, type=Unknown, state=Connecting, exception={com.mongodb.MongoException$Network: Exception opening the socket}, caused by {java.io.EOFException}}]; nested exception is com.mongodb.MongoTimeoutException: Timed out after 10000 ms while waiting to connect. Client view of cluster state is {type=Unknown, servers=[{address=test.mongo.com:27017, type=Unknown, state=Connecting, exception={com.mongodb.MongoException$Network: Exception opening the socket}, caused by {java.io.EOFException}}] 
    at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:75) 
    at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2075) 
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1918) 

缺少什么我在这里先谢谢了!

回答

0

除了用命令导入CAFile.pem:

(浏览到您的java_home/jre/lib/security运行命令)

1. keytool -import -trustcacerts -file testCA.pem -keystore cacerts -storepass "changeit"

我也不得不出口的关键。进入pkcs12格式(默认密码'changeit')

2. openssl pkcs12 -export -out mongodb.pkcs12 -in testKey.pem

,并在除了设置系统属性的trustStore /口令,密钥库/密码,也应设置:

System.setProperty ("javax.net.ssl.trustStore",javaHome + "\\lib\\security\\cacerts"); 
System.setProperty ("javax.net.ssl.trustStorePassword","changeit"); 
System.setProperty ("javax.net.ssl.keyStore",javaHome + "\\lib\\security\\mongodb.pkcs12"); 
System.setProperty ("javax.net.ssl.keyStorePassword","changeit"); 
+0

我有完全一样的问题,但它仍然不是为我工作,我在Linux上运行的窗口,以便从“testKey.pem”创建xyz.pkcs12和密钥存储复制它交给窗口和进口的相同,没有任何东西否则我应该这样做? – Amit

+0

@Amit你可以发布你的stacktrace吗? – Gurkha

+0

javax.net.ssl.SSLHandshakeException:java.security.cert.CertificateException:本 \t在sun.security.ssl.Alerts.getSSLException(未知来源) \t在sun.security.ssl.SSLSocketImpl.fatal没有使用者替代名称(未知来源) \t在sun.security.ssl.Handshaker.fatalSE(未知来源) \t在sun.security.ssl.Handshaker.fatalSE(未知来源) \t在sun.security.ssl.ClientHandshaker.serverCertificate(未知来源) \t at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source) \t at sun.security.ssl.Handshaker.processLoop(Unknown Source) – Amit

1

您需要将monog db驱动程序配置为使用SSL。您可以在@Configuration类中手动配置它。

public @Bean MongoClient mongo() { 
     MongoClientOptions.Builder options = MongoClientOptions.builder().sslEnabled(true); 
     // add more options to the builder with your config 
     MongoClient mongoClient = new MongoClient("localhost", options.build()); 
     return mongoClient; 
    } 
+1

我通过URI启用SSL:'test.mongo.com:27017/TESTDB SSL = TRUE; – Gurkha

+0

afiak Mongo数据库URI。无法使用主机,端口和凭证进行设置。它使用只接受主机和端口的内部ServerAddress类。 – Redlab

+0

是的,它可以http://mongodb.github.io/mongo-java-driver/3.0/driver/reference/connecting/ssl/?_ga=1.246548100.1027948420.1459173085' – Gurkha

1

无论是低于通常所提到的方法在论坛上会“工作”但并不安全的建议他们禁用主机名验证,实质上否定了SSL。因此,他们并不特别推荐,如果你的代码将在生产部署:

// 1. For any HTTPS connection 
    javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
     new javax.net.ssl.HostnameVerifier(){ 
      public boolean verify(String hostname, 
       javax.net.ssl.SSLSession sslSession) { 
        if(hostname.equals("<hostname>")) { 
         return true; 
        } 
       } 
      }); 

// 2. MongoDB SSL specific 
MongoClientOptions.builder().sslEnabled(true).sslInvalidHostNameAllowed(true).build(); 

参见:https://wiki.openssl.org/index.php/Hostname_validation


要解决这个问题,你需要包含服务器的DNS作为一个证书主题备用名称条目,您可以将其导入到JDK中cacerts

或者,如果要在应用程序级别建立SSL,则建议为该特定连接创建SSLContext使用System.setProperty()设置密钥库/信任库。如果您的应用程序连接到具有不同SSL实现的不同外部服务,这将有助于避免冲突。


具体MongoDB的,你只需要在MongoDBURI的上述步骤之后,最终追加?ssl=true。如果还是不行,我建议您更新的JDK版本按https://jira.mongodb.org/browse/JAVA-2184

希望这有助于

相关问题