I have a MongoDb
instance running(single instance) with SSL
enabled. I am able to connect to it with RoboMongo
where on SSL
tab I provide the following :
CA File : /path to my certificate/testCA.pem
PEM certificate/key: /path to my key/testKey.pem
Which successfully connects. Now I'm trying to connect to the same mondodb from java app. I imported the testCA.pem into cacerts using the following command:
keytool -import -keystore cacerts -file testCA.pem -storepass changeit
and I can see a new entry added to the store. Tried to add the other key into it and it says invalid certificate. On the Java app I set system property as following:
System.setProperty ("javax.net.ssl.trustStore","C:\\Program Files\\Java\\jre1.8.0_91\\lib\\security\\cacerts");
System.setProperty ("javax.net.ssl.trustStorePassword","changeit");
and I'm getting the following error:
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)
What am I missing here, thanks in advance!
If you are using RAD with WAS local servers, you have to add the pem file to the java VM for that server.
So if you have WAS installed to X:\IBM\WASx, X:\IBM\WASx\java_17\jre is the directory that you would navigate and then execute the keytool import there. Hope this helps others.
In addition to importing the
CAFile.pem
with the command:(navigate to your
java_home/jre/lib/security
to run the commands)1. keytool -import -trustcacerts -file testCA.pem -keystore cacerts -storepass "changeit"
I also had to export the
key.pem
into apkcs12
format(default password'changeit'
)2. openssl pkcs12 -export -out mongodb.pkcs12 -in testKey.pem
and in addition to setting system property trustStore/password, keyStore/password should also be set:
Both the approaches mentioned below usually suggested on forums will 'work' but are not secure as they disable the host-name verification essentially negating the SSL. Hence they are not recommended especially if your code would be deployed on production:
Refer: https://wiki.openssl.org/index.php/Hostname_validation
To fix this, you'll need a certificate containing the DNS of the server as a Subject Alternative Name entry, which you can import to your JDK
cacerts
Alternatively, if you want establish SSL at the application level, I'd recommend creating a
SSLContext
for that particular connection instead of usingSystem.setProperty()
for setting key-stores/trust-stores. This would help in avoiding conflicts if your application connects to different external services who have different SSL implementations.Specifically for MongoDB, you would just need to append
?ssl=true
at the end of the MongoDBURI after the above mentioned step. If it still doesn't work, I'd recommend updating your JDK version as per https://jira.mongodb.org/browse/JAVA-2184Hope this helps
You need to configure the monog db driver to use SSL. You can do this with configuring it manually in a @Configuration class.