MongoDB Java driver ssl 加密连接,自定义KeyManager TrustManager

微生令
2023-12-01

MongoDB Java driver ssl 加密连接,自定义KeyManager TrustManager

关于SSL验证,非对称加密流程:https://blog.csdn.net/fzlulee/article/details/99690242 https://blog.csdn.net/qq_31825569/article/details/7995696

http://mongodb.github.io/mongo-java-driver/3.0/driver/reference/connecting/ssl/

https://www.jianshu.com/p/5fcc6a219c8b

https://blog.csdn.net/anningzhu/article/details/77484212

https://blog.csdn.net/ywb201314/article/details/72830466

https://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#Customization

添加服务端证书至JVM证书库,准备客服端可以store,通过System setProperty设置程序运行时属性

  • 添加服务端证书(或自签名root根证书)至JVM证书库(这里添加到$JAVA_HOME/jre/lib/security/cacerts证书库中, 密码默认changeit)
    • keytool -import -alias yourAlias -keystore cacerts -file /path/to/server.crt -storepass changeit
  • 可能需要转换client.pem pem格式证书和私钥为java支持的格式,这里用pkcs12格式
    • openssl pkcs12 -export -out yourTrustStoreName -in /path/to/client.pem
import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;
import org.bson.Document;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class App {
    public static void main(String[] args) {
        System.setProperty("javax.net.ssl.trustStore","/path/to/truststore");
        System.setProperty("javax.net.ssl.keyStore","/path/to/keystore");
        System.setProperty("javax.net.ssl.trustStorePassword","changeit");
        System.setProperty("javax.net.ssl.keyStorePassword","changeit");
        //        System.setProperty("jdk.tls.allowUnsafeServerCertChange", "true");
        //        System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");

        ServerAddress serverAddress = new ServerAddress("host1",27017);
        ServerAddress serverAddress2 = new ServerAddress("host2",27017);
        List<ServerAddress> addrs = new ArrayList<ServerAddress>();
        addrs.add(serverAddress);
        addrs.add(serverAddress2);
        MongoCredential credential = MongoCredential.createCredential("username",
          "authdb", "password".toCharArray());
        List<MongoCredential> crens = new ArrayList<MongoCredential>();
        crens.add(credential);
        MongoClientOptions sslOptions = MongoClientOptions.builder().sslEnabled(true).
          socketFactory(getNoopSslSocketFactory()).sslInvalidHostNameAllowed(true).build();
        MongoClient mongoClient = new MongoClient(addrs, crens, sslOptions);

        // list all dbs
        MongoIterable<String> dbs =  mongoClient.listDatabaseNames();
        for (String s : dbs) {
            System.out.println(s);
        }
        mongoClient.close();
    }

自定义KeyManager TrustManager,生成定制SSLContext实例

不同格式间证书转换: https://www.cnblogs.com/cuimiemie/p/6442668.html

  • 通过System setProperty设置程序运行时属性的方式,可能会增加程序的不安全性,特别是在使用第三方库的时候。自定义KeyManager TrustManager,生成定制SSLContext实例可以解决这个问题,而且不会污染系统属性。
  • 不需要添加服务端证书至JVM证书库,只需在程序中指定jdk支持格式的证书、client端keystore即可。
  • 使用server.crt 和 server.key 生成jdk支持的格式的truststore文件
    • openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name server_pkcs12
  • 可能需要转换client.pem pem格式证书和私钥为java支持的格式,这里用pkcs12格式
    • openssl pkcs12 -export -out yourTrustStoreName -in /path/to/client.pem
            String keyStorePath = "/path/to/keystore";
            String keyStorePwd = "changeit";
            String trustStorePath = "/path/to/truststore";
            String trustStorePwd = "changeit";
            SSLContext sslContext;            
            sslContext = SSLContext.getInstance("SSL");

            // set up a KeyManager for validation of server side if required
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); // usually is jks
            FileInputStream myKeyStore = new FileInputStream(keyStorePath);
            keyStore.load(myKeyStore,keyStorePwd.toCharArray());
            myKeyStore.close();
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
              .getDefaultAlgorithm()); // default SunX509
            kmf.init(keyStore, keyStorePwd.toCharArray());

            // set up a TrustManager that trusts everything
            // 1.trust specific trustStore
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            TrustManagerFactory tmf = TrustManagerFactory
              .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            FileInputStream myTrustStore = new FileInputStream(trustStorePath);
            trustStore.load(myTrustStore,trustStorePwd.toCharArray());
            myTrustStore.close();
            tmf.init(trustStore);
            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
//            // 2. trust all server certificates
//            sslContext.init(kmf.getKeyManagers(), new TrustManager[] { new X509TrustManager() {
//                @Override
//                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
//                @Override
//                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {}
//                @Override
//                public X509Certificate[] getAcceptedIssuers() {
//                    return new X509Certificate[0];
//                }
//            }}, new SecureRandom());
        MongoClientOptions sslOptions = MongoClientOptions.builder().sslEnabled(true).
          socketFactory(getNoopSslSocketFactory()).sslInvalidHostNameAllowed(true).build();
        MongoClient mongoClient = new MongoClient(addrs, crens, sslOptions);

<全文完>

 类似资料: