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

<全文完>

发布了15 篇原创文章 · 获赞 1 · 访问量 1837
展开阅读全文

我生成的mongoDB的证书文件,应该如何用呢?

10-14

1.问题 目前我生成了X509证书: ca-cert.pem: CA 证书, 用于生成服务器端/客户端的数字证书. ca.pem: CA 私钥, 用于生成服务器端/客户端的数字证书. server-key.pem: 服务器端的 RSA 私钥 server-req.pem: 服务器端的证书请求文件, 用于生成服务器端的数字证书. server-cert.pem: 服务器端的数字证书. client-key.pem: 客户端的 RSA 私钥 client-req.pem: 客户端的证书请求文件, 用于生成客户端的数字证书. client-cert.pem: 客户端的数字证书. 生成语句: openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 7200 -key ca-key.pem -out ca.pem openssl req -newkey rsa:2048 -days 7200 -nodes -keyout server-key.pem -out server-req.pem openssl rsa -in server-key.pem -out server-key.pem openssl x509 -req -in server-req.pem -days 7200 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem openssl req -newkey rsa:2048 -days 7200 -nodes -keyout client-key.pem -out client-req.pem openssl rsa -in client-key.pem -out client-key.pem openssl x509 -req -in client-req.pem -days 7200 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem 现在我想把证书加入到mongo.cnf中,但是无论如何加客户端都无法连上服务端 2.描述 我将cat server-key.pem server-cert.pem > server.pem cat client-key.pem client-cert.pem > client.pem mongodb.cnf的配置信息 net: port: 27017 ssl: mode: requireSSL PEMKeyFile: /data/db/mongo_key/server.pem PEMKeyPassword: wanbang123 CAFile: /data/db/mongo_key/client.pem allowConnectionsWithoutCertificates: true allowInvalidHostnames: true allowInvalidCertificates: true 目前java端使用的证书为: keytool -importcert -alias MySQLCACert -file ca.pem -keystore xxx.jks -storepass wanbang123 连接语句: ./bin/mongo --host 127.0.0.1:27018 --ssl --sslPEMKeyFile /data/db/mongo_key/client.pem --sslCAFile /data/db/mongo_key/server.pem --sslAllowInvalidHostnames 3.报错信息 2019-10-14T09:49:19.480+0800 E NETWORK [thread1] SSL peer certificate validation failed: unable to verify the first certificate 2019-10-14T09:49:19.480+0800 E QUERY [thread1] Error: socket exception [CONNECT_ERROR] for SSL peer certificate validation failed: unable to verify the first certificate :connect@src/mongo/shell/mongo.js:231:14 日志信息 2019-10-14T09:51:04.153+0800 I NETWORK [initandlisten] connection accepted from 172.17.0.1:38354 #1 (1 connection now open) 2019-10-14T09:51:04.172+0800 W NETWORK [conn1] SSL peer certificate validation failed: unable to verify the first certificate 2019-10-14T09:51:04.173+0800 I NETWORK [conn1] end connection 172.17.0.1:38354 (0 connections now open) 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览