2017-02-17 111 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

希望這有助於

相關問題