MongoDB Java driver ssl 加密連接,自定義KeyManager TrustManager

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);

<全文完>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章