MongoDB使用x.509证书认证

news2025/5/13 17:50:01

文章目录

  • 自定义证书
    • 生成CA证书
    • 生成服务器之间的证书
    • 生成集群证书
    • 生成用户证书
  • MongoDB配置
  • java使用x.509证书连接MongoDB
  • MongoShell使用证书连接

8.0版本的mongodb开启复制集,配置证书认证

自定义证书

生成CA证书

生成ca私钥: openssl genrsa -out ca.key 4096 # 生成RSA 4096位私钥
生成ca证书: openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt -subj "/CN=MongoDB Root CA/O=MyOrg/OU=Security"
验证ca证书: openssl x509 -in ca.crt -text -noout
生成pkcs12格式的p12文件:后续用于java代码认证
cat ca.crt ca.key > ca.pem
openssl pkcs12 -export -in ca.pem -out ca.p12 -password pass:123456

生成服务器之间的证书

生成服务器私钥: openssl genrsa -out server.key 2048
生成证书签名请求: openssl req -new -key server.key -out server.csr -subj "/CN=1.1.1.1/O=MyOrg/OU=Servers"
生成扩展配置文件(server.ext):

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:mongodb-server.example.com,DNS:localhost,IP:192.168.1.100

用ca签发证书: openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256 -extfile server.ext
合并证书与私钥: cat server.crt server.key > server.pem
验证服务器证书: openssl verify -CAfile ca.crt server.crt # 应显示 “OK”

生成集群证书

生成集群私钥: openssl genrsa -out cluster.key 2048
生成CSR : openssl req -new -key cluster.key -out cluster.csr -subj "/CN=node1/O=MyOrg/OU=MongoDB-Cluster" 必须包含一致的 O(组织)或 OU(部门),否则集群节点无法相互认证。
生成扩展配置文件(cluster.ext):

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, keyEncipherment
extendedKeyUsage=clientAuth

ca签发集群证书: openssl x509 -req -in cluster.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cluster.crt -days 365 -sha256 -extfile cluster.ext
合并证书与私钥: cat cluster.crt cluster.key > cluster.pem
验证集群证书:
openssl x509 -in cluster.crt -text | grep "Subject:" # 确认O/OU一致性
openssl verify -CAfile ca.crt cluster.crt # 应显示 “OK”

生成用户证书

生成用户私钥: openssl genrsa -out zy1.key 2048
生成CSR : openssl req -new -key zy1.key -out zy1.csr -subj "/O=MyOrg/CN=zy1" 必须包含一致的 O(组织)或 OU(部门),否则集群节点无法相互认证。
生成扩展配置文件( zy1.ext):

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=digitalSignature, keyEncipherment
extendedKeyUsage=clientAuth

ca签发集群证书: openssl x509 -req -in zy1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out zy1.crt -days 365 -sha256 -extfile zy1.ext
合并证书与私钥: cat zy1.crt zy1.key > zy1.pem
获取subject : openssl x509 -in /usr/local/database/mongodb8.0.5/crt/zy1.pem -inform PEM -subject -nameopt RFC2253

生成pkcs12 格式的信任库文件:
openssl pkcs12 -export -inkey zy1.pem -in zy1.pem -out zy1_pem.p12 -password pass:123456
测试PKCS12密码正确性
keytool -list -v -keystore C:\Users\Administrator\Desktop\crt\zy1_pem.p12 -storetype pkcs12

MongoDB配置

mongodb配置:

     # mongod.conf
 net:
   tls:
     mode: requireTLS
     CAFile: /path/to/ca.crt
     certificateKeyFile: /path/to/server.pem
     clusterFile: /path/to/cluster.pem
 security:
   clusterAuthMode: x509
   authorization: enabled	

所有pem文件的权限都设为600 : chmod 600 ca.crt server.pem cluster.pem
客户端的证书由同一CA签发,并且在Mongodb中创建对应用户,如下:用户名为O=MyOrg,CN=zy,需要与证书中的Subject保持一致。可以通过名命令获取:
openssl x509 -in /usr/local/database/mongodb8.0.5/crt/zy1.pem -inform PEM -subject -nameopt RFC2253

db.getSiblingDB("$external").runCommand(
  {
    createUser: "O=MyOrg,CN=zy",
    roles: [
         { role: "readWrite", db: "test" },
         { role: "userAdminAnyDatabase", db: "admin" }
    ],
    writeConcern: { w: "majority" , wtimeout: 5000 }
  }
)

java使用x.509证书连接MongoDB

package com.zy.sslcontext;

import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * Connect to a MongoDB cluster with TLS connection.
 * Validate MongoDB server's certificate with the CA certificate. Present a Client certificate to be validated by
 * the MongoDB server.
 *
 * Use X509 certificate to authenticate with the MongoDB server
 *
 * Create a custom {@link javax.net.ssl.SSLContext} with the TrustStore holding the CA certificate and
 * the KeyStore holding the Client certificate and provide it to the MongoDB Driver.
 */
public class ValidateServerPresentClientCertificateX509Auth {

    public static void main(String[] args) {
	//     System.setProperty("javax.net.debug", "ssl:handshake:verbose");

        // Configure MongoDB Driver to use MONGODB-X509 as authentication mechanism
        // 此处url可以不用填写用户名密码,则后续配置时采用credential(MongoCredential.createMongoX509Credential())使用证书在的用户信息进行数据操作
        String connectionString = "mongodb://zy:123456@1.1.1.1:27017/?&ssl=true"; 

        SSLContext sslContext;
        try {
            sslContext = getSSLContext();
        } catch (Exception e) {

            System.out.println("Failed to generate SSLContext. Error: " + e.getMessage());
            return;
        }

        MongoClientSettings settings = MongoClientSettings.builder()
                .applyConnectionString(new ConnectionString(connectionString)) 
                .applyToSslSettings(builder -> {
                    builder.enabled(true); // 开启ssl
                    builder.context(sslContext);
                })
//                .credential(MongoCredential.createCredential("zy","admin","123456".toCharArray()))
//                .credential(MongoCredential.createMongoX509Credential("O=MyOrg,CN=zy"))
//                .credential(MongoCredential.createMongoX509Credential())
                .applyToConnectionPoolSettings(builder -> builder
                        .maxSize(1)          // 总最大连接数(所有实例总和)
                        .minSize(1)           // 总最小空闲连接数
                        .maxWaitTime(1500, TimeUnit.MILLISECONDS)
                        .maxConnectionIdleTime(10, TimeUnit.MINUTES)
                )
                .applyToSocketSettings(b -> b
                        .connectTimeout(3000, TimeUnit.MILLISECONDS)
                        .readTimeout(5000, TimeUnit.MILLISECONDS)
                )
                .build();

        MongoClient client = MongoClients.create(settings);

        MongoDatabase test = client.getDatabase("test");
        MongoCollection<Document> coll  = test.getCollection("collection1");

        // Retrieve the first document and print it
        System.out.println(coll.getNamespace());
        System.out.println(coll.find().first());

        MongoCollection<Document> collection = client.getDatabase("zy").getCollection("test1");
        collection.find().forEach(System.out::println);
    }

    /**
     * Load CA certificate from the file into the Trust Store.
     * Use PKCS12 keystore storing the Client certificate and read it into the {@link KeyStore}
     * Generate {@link SSLContext} from the Trust Store and {@link KeyStore}
     *
     * @return SSLContext
     *
     * @throws IOException
     * @throws CertificateException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     */
    private static SSLContext getSSLContext() throws IOException, CertificateException,
            NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException {

//        String certsPath = System.getProperty("cert_path");
        String certsPath = "C:\\Users\\Administrator\\Desktop\\crt\\";

        // Path to the CA certificate on disk
        String caCertPath = certsPath + "ca.crt";

        // 避坑:使用JKS认证失败
        // openssl pkcs12 -export -inkey zy.key -in zy.pem -out zy.p12
        // Path to the PKCS12 Key Store holding the Client certificate
        String clientCertPath = certsPath + "zy1_pem.p12";
        String clientCertPwd  = "123456";
        SSLContext sslContext;

        try (
                InputStream caInputStream = new FileInputStream(caCertPath);
                InputStream clientInputStream = new FileInputStream(clientCertPath)
        ) {
            // Read Client certificate from PKCS12 Key Store
            KeyStore clientKS = KeyStore.getInstance("PKCS12");
            clientKS.load(clientInputStream, clientCertPwd.toCharArray());

            // Retrieve Key Managers from the Client certificate Key Store
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            kmf.init(clientKS, clientCertPwd.toCharArray());
            KeyManager[] keyManagers = kmf.getKeyManagers();

            // Read CA certificate from file and convert it into X509Certificate
            CertificateFactory certFactory = CertificateFactory.getInstance("X509");
            X509Certificate caCert = (X509Certificate)certFactory.generateCertificate(caInputStream);

            KeyStore caKS = KeyStore.getInstance(KeyStore.getDefaultType());
            caKS.load(null);
            caKS.setCertificateEntry("caCert", caCert);

            // Initialize Trust Manager
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(caKS);

            // Create SSLContext. We need Trust Manager only in this use case
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(keyManagers, tmf.getTrustManagers(), null);
        }

        return sslContext;
    }
}

MongoShell使用证书连接

./mongosh --host 1.1.1.1 --tls --tlsCAFile /usr/local/database/mongodb8.0.5/crt/ca.crt --tlsCertificateKeyFile /usr/local/database/mongodb8.0.5/crt/zy.pem --authenticationDatabase '$external' --authenticationMechanism MONGODB-X509

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2374830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【RabbitMQ】应用问题、仲裁队列(Raft算法)和HAProxy负载均衡

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【中间件】企业级中间件剖析 一、幂等性保障 什么是幂等性&#xff1f; 幂等性是指对一个系统进行重复调用&#xff08;相同参数&#xff09;&#xff0c;无论同一操作执行多少次&#xff0c;这些请求…

软件设计师-错题笔记-系统开发与运行

1. 解析&#xff1a; A&#xff1a;模块是结构图的基本成分之一&#xff0c;用矩形表示 B&#xff1a;调用表示模块之间的调用关系&#xff0c;通过箭头等符号在结构图中体现 C&#xff1a;数据用于表示模块之间的传递的信息&#xff0c;在结构图中会涉及数据的流向等表示 …

C#简易Modbus从站仿真器

C#使用NModbus库&#xff0c;编写从站仿真器&#xff0c;支持Modbus TCP访问&#xff0c;支持多个从站地址和动态启用/停用从站&#xff08;模拟离线&#xff09;&#xff0c;支持数据变化&#xff0c;可以很方便实现&#xff0c;最终效果如图所示。 项目采用.net framework 4.…

【深度学习】目标检测算法大全

目录 一、R-CNN 1、R-CNN概述 2、R-CNN 模型总体流程 3、核心模块详解 &#xff08;1&#xff09;候选框生成&#xff08;Selective Search&#xff09; &#xff08;2&#xff09;深度特征提取与微调 2.1 特征提取 2.2 网络微调&#xff08;Fine-tuning&#xff09; …

视觉-语言-动作模型:概念、进展、应用与挑战(下)

25年5月来自 Cornell 大学、香港科大和希腊 U Peloponnese 的论文“Vision-Language-Action Models: Concepts, Progress, Applications and Challenges”。 视觉-语言-动作 (VLA) 模型标志着人工智能的变革性进步&#xff0c;旨在将感知、自然语言理解和具体动作统一在一个计…

一键解锁嵌入式UI开发——LVGL的“万能配方”

面对碎片化的嵌入式硬件生态&#xff0c;LVGL堪称开发者手中的万能配方。它通过统一API接口屏蔽底层差异&#xff0c;配合丰富的预置控件&#xff08;如按钮、图表、滑动条&#xff09;与动态渲染引擎&#xff0c;让工程师无需深入图形学原理&#xff0c;效率提升肉眼可见。 L…

智慧城市综合运营管理系统Axure原型

这款Axure原型的设计理念紧紧围绕城市管理者的需求展开。它旨在打破传统城市管理中信息孤岛的局面&#xff0c;通过统一标准接入各类业务系统&#xff0c;实现城市运营管理信息资源的全面整合与共享。以城市管理者为中心&#xff0c;为其提供一个直观、便捷、高效的协同服务平台…

Qwen智能体qwen_agent与Assistant功能初探

Qwen智能体qwen_agent与Assistant功能初探 一、Qwen智能体框架概述 Qwen&#xff08;通义千问&#xff09;智能体框架是阿里云推出的新一代AI智能体开发平台&#xff0c;其核心模块qwen_agent.agent提供了一套完整的智能体构建解决方案。该框架通过模块化设计&#xff0c;将L…

可视化图解算法37:序列化二叉树-II

1. 题目 描述 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树&#xff0c;不对序列化之后的字符串进行约束&#xff0c;但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。 二叉树的序列化(Serialize)是指&#xff1a;把一棵二叉树按照某种遍…

C++GO语言微服务和服务发现②

01 创建go-micro项目-查看生成的 proto文件 02 创建go-micro项目-查看生成的main文件和handler ## 创建 micro 服务 命令&#xff1a;micro new --type srv test66 框架默认自带服务发现&#xff1a;mdns。 使用consul服务发现&#xff1a; 1. 初始consul服务发现&…

【Web前端开发】CSS基础

2.CSS 2.1CSS概念 CSS是一组样式设置的规则&#xff0c;称为层叠样式表&#xff0c;用于控制页面的外观样式。 使用CSS能够对网页中元素位置的排版进行像素控制&#xff0c;实现美化页面的效果&#xff0c;也能够做到页面的样式和结构分离。 2.2基本语法 通常都是&#xff…

Git实战经验分享:深入掌握git commit --amend的进阶技巧

一、工具简介 git commit --amend是Git版本控制系统的核心补救命令&#xff0c;主要用于修正最近一次提交的元数据。该命令不会产生新的提交记录&#xff0c;而是通过覆盖原提交实现版本历史的整洁性&#xff0c;特别适合在本地仓库进行提交优化。 二、核心应用场景 提交信息…

PTA:jmu-ds-最短路径

给定一个有向图&#xff0c;规定源点为0&#xff0c;求源点0到其他顶点最短路径。###你要实现的 函数接口定义&#xff1a; void Dijkstra(MGraph g,int v);//源点v到其他顶点最短路径 裁判测试程序样例&#xff1a; #include <stdio.h> #include <iostream> …

WEB UI自动化测试之Pytest框架学习

文章目录 前言Pytest简介Pytest安装Pytest的常用插件Pytest的命名约束Pytest的运行方式Pytest运行方式与unittest对比主函数运行命令行运行执行结果代码说明 pytest.ini配置文件方式运行&#xff08;推荐&#xff09;使用markers标记测试用例 pytest中添加Fixture&#xff08;测…

深入理解 iOS 开发中的 `use_frameworks!`

在使用 CocoaPods 管理 iOS 项目依赖时&#xff0c;开发者经常会在 Podfile 文件中看到一个配置选项&#xff1a;use_frameworks!。本文将详细介绍这个配置选项的含义&#xff0c;以及如何决定是否在项目中使用它。 一、什么是 use_frameworks! 在 CocoaPods 中引入第三方库时…

矩阵置零算法讲解

矩阵置零算法讲解 一、问题描述 给定一个 (m \times n) 的矩阵,如果一个元素为 (0) ,则将其所在行和列的所有元素都设为 (0) 。要求使用原地算法,即在不使用额外矩阵空间的情况下完成操作。 二、解题思路 暴力解法 最直观的想法是遍历矩阵,当遇到 (0) 元素时,直接将其…

二本计算机,毕业=失业?

我嘞个豆&#xff0c;二本计算机&#xff0c;毕业即失业&#xff1f;&#xff01; 今天咱们聊聊普通院校计算机专业的学生未来的发展方向。有些话可能不太中听&#xff0c;但希望大家能理性看待。 首先得承认&#xff0c;对于普通双非和二本的学生来说&#xff0c;就业率加上…

[docker基础二]NameSpace隔离实战

目录 一 实战目的 二 基础知识 1)dd 命令详解 2)mkfs命令详解 3)df命令详解 4)mount 命令详解 5)unshare命令详解 三 实战操作一(PID隔离) 四 实战操作二(MOunt隔离) 1&#xff09;创建 Mount 隔离进程 2&#xff09;在新进程里边&#xff0c;创建空白文件&#…

Day22打卡-复习

复习日 仔细回顾一下之前21天的内容&#xff0c;没跟上进度的同学补一下进度。 作业&#xff1a; 自行学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号人员生还预测https://www.kaggle.com/competitions/titanic/overview K…

uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图)

uniapp + vue3 + 京东Nut动作面板组件:实现登录弹框组件(含代码、案例、小程序截图) 代码示下,不再赘述。 动作面板组件:https://nutui-uniapp.netlify.app/components/feedback/actionsheet.html 项目背景 业务需求 描述: uniapp + vue3 + 京东Nut框架:实现登录弹框组…