1

QUESTION:

I have CA Certificate as cafile.pem, PEM Certificate as mongodb.pem. I am not sure how to use it in java to authentication and connect MongoDB. Any suggestion would be deeply appreciate. Let me know if you want more information to put up.

Scenario:

I am using mongo-java-driver-3.4.3.jar to connect to an SSL enabled, Authentication enabled MongoDB 3.7.9 sharded cluster with 3 instances. Below is the java code I am trying to connect to this server.

import java.util.ArrayList;
import java.util.List;

import org.bson.Document;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ReadPreference;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;

public class Starter {

    public static void main(String[] args){

        List<MongoCredential> mongoCredentials = new ArrayList<MongoCredential>();
        mongoCredentials.add(MongoCredential.
        createScramSha1Credential("admin", "admin", "admin".toCharArray()));

        List<ServerAddress> serverAddressArray = new ArrayList<ServerAddress>();

        serverAddressArray.add(new ServerAddress("xyz.domain.com", 27017));

        MongoClientOptions options = new MongoClientOptions.Builder()
                                        .sslInvalidHostNameAllowed(false)
                                        .sslEnabled(true)
                                        .readPreference(ReadPreference.primaryPreferred())
                                        .build();
        MongoClient mongoClient = new MongoClient(serverAddressArray, mongoCredentials, options);
        try {
            System.out.println("----- Step 1 ------");
            MongoDatabase db = mongoClient.getDatabase("CIM");
            System.out.println("----- Step 2 ------");
            MongoCollection<Document> collection = db.getCollection("orders");
            System.out.println("No of Documents in orders collection: " + collection.count());
          } catch (Exception ex) {
              System.out.println(ex.getMessage());
          }
    }       
}

I get below error;

----- Step 1 ------
----- Step 2 ------
Sep 20, 2018 2:48:02 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: No server chosen by ReadPreferenceServerSelector{readPreference=ReadPreference{name=primaryPreferred}} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=MULTIPLE, serverDescriptions=[ServerDescription{address=torvm-core16.sigma-systems.com:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
Sep 20, 2018 2:48:03 PM com.mongodb.diagnostics.logging.JULLogger log
INFO: Exception in monitor thread while connecting to server xyz.domain.com:27017
com.mongodb.MongoSocketReadException: Prematurely reached end of stream
    at com.mongodb.connection.SocketStream.read(SocketStream.java:88)
    at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java:494)
    at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java:224)
    at com.mongodb.connection.CommandHelper.receiveReply(CommandHelper.java:134)
    at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:121)
    at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
    .............

Anyways I am able to connect MongoServer as below configuration in RoboMongo3T.

enter image description here

mongodb.pem

Bag Attributes
    localKeyID: AA 4A 8D C5 AC CE 7A 08 F6 F1 00 2C 78 20 8D 0C 51 DE 66 F5 
subject=/OU=Domain Control Validated/CN=*.xyz.com
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIIFPzCCBCegAwIBAgIJAKpTjrMr7rpZMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
.
.
.
-----END CERTIFICATE-----
Bag Attributes: <No Attributes>
subject=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certs.godaddy.com/repository//CN=Go Daddy Secure Certificate Authority - G2
issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIIFPzCCBCegAwIBAgIJAKpTjrMr7rpZMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
.
.
.
-----END CERTIFICATE-----
Bag Attributes
    localKeyID: AA 4A 8D C5 AC CE 7A 08 F6 F1 00 2C 78 20 8D 0C 51 DE 66 F5 
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIFPzCCBCegAwIBAgIJAKpTjrMr7rpZMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD
.
.
.
-----END PRIVATE KEY-----

cafile.pem

-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
.
.
.
.
.

-----END CERTIFICATE-----
Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
Ankur Soni
  • 5,725
  • 5
  • 50
  • 81

1 Answers1

1
  1. I first created a mongodb.pkcs12 file using command openssl pkcs12 -export -out mongodb.pkcs12 -in mongodb.pem.
  2. I had to include this file in the file path for keyStore and trustStore in below code (NOTE: My code has also changed and minimized).

    import org.bson.Document;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    
    public class Starter {
    
        private static MongoClient mongoClient;
    
        public static void main(String[] args) {
    
            System.setProperty("javax.net.ssl.trustStore", "mongodb.pkcs12");
            System.setProperty("javax.net.ssl.trustStorePassword", "yourPassword");
            System.setProperty("javax.net.ssl.keyStore", "mongodb.pkcs12");
            System.setProperty("javax.net.ssl.keyStorePassword", "yourPassword");
    
            MongoClientURI mongoClientURI = new MongoClientURI(
                    "mongodb://admin:admin@hostname3.xyz.com,hostname2.xyz.com:27017,hostname3.xyz.com:27017/admin?ssl=true");
            mongoClient = new MongoClient(mongoClientURI);
    
            try {
                MongoDatabase db = mongoClient.getDatabase("CIM");
                MongoCollection<Document> collection = db.getCollection("orders");
                System.out.println("No of Documents in orders collection: "
                        + collection.count());
            } catch (Exception ex) {
                System.out.println(ex.getMessage());
            }
        }
    }
    

Above code is working very well and below is the output I got,

    Sep 24, 2018 3:49:13 PM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Discovered cluster type of SHARDED
    Sep 24, 2018 3:49:15 PM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Opened connection [connectionId{localValue:4}] to hostname3.xyz.com:27017
    No of Documents in orders collection: 3
Ankur Soni
  • 5,725
  • 5
  • 50
  • 81
  • I have the same problem except that I dont have a ".pem" file but a ".crt" file, and want to access my db with tls. Do you know how to proceed? Or how to create the keystore without the pem file? – Asdf11 Dec 11 '21 at 19:09