openssl 生成多域名 多IP 的数字证书

news2025/2/23 7:28:05

openssl.cnf 文件内容:

复制代码

[req]
default_bits  = 2048
distinguished_name = req_distinguished_name
copy_extensions = copy
req_extensions = req_ext
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
countryName = CN
stateOrProvinceName = GuangDong
localityName = ShenZhen
organizationName = lc
commonName = CA
[req_ext]
basicConstraints = CA:FALSE
subjectAltName = @alt_names
[v3_req]
basicConstraints = CA:FALSE
subjectAltName = @alt_names
[alt_names]
IP.1 = 192.168.10.31
IP.2 = 192.168.10.32
IP.3 = 192.168.10.33
DNS.1 = 192.168.10.2
DNS.2 = 202.96.134.133

复制代码

生成证书

工具是用的:windows平台  Win64OpenSSL-3_2_0.exe   或  Win64OpenSSL_Light-3_2_0.exe    (建议用:Win64OpenSSL-3_2_0.exe )

OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

复制代码

根证书:
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem -subj "/C=CN/ST=GuangDong/O=EMQX/CN=Client"
服务端证书:
openssl genrsa -out emqx.key 2048
openssl req -new -key emqx.key -config openssl.cnf -out emqx.csr
openssl x509 -req -in emqx.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out emqx.pem -days 3650 -sha256 -extensions v3_req -extfile openssl.cnf
客户端证书:
openssl genrsa -out client.key 2048
openssl req -new -key client.key -out client.csr -subj "/C=CN/ST=GuangDong/O=EMQX/CN=Client"
openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem
校验证书的有效性:
openssl verify -CAfile ca.pem emqx.pem
openssl verify -CAfile ca.pem client.pem

复制代码

常见错误:

Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: IP: 192.168.10.32 is not in the cert's list:
Error: self signed certificate in certificate chain
Error: Connection refused: Not authorized # 没有设置用户名密码
Error: unable to verify the first certificate

加密认证算法:

复制代码

package com.lc.common.mqtt.utils;

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;
import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

/**
 * @author Charley
 * @date 2022/12/05
 * @description
 */
@Component
public class SSLUtils {


    @javax.annotation.Resource
    private  ResourceLoader resourceLoader;

    public  SSLSocketFactory getSingleSocketFactory(InputStream caCrtFileInputStream) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        X509Certificate caCert = null;

        BufferedInputStream bis = new BufferedInputStream(caCrtFileInputStream);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        while (bis.available() > 0) {
            caCert = (X509Certificate) cf.generateCertificate(bis);
        }
        KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
        caKs.load(null, null);
        caKs.setCertificateEntry("cert-certificate", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(caKs);
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext.getSocketFactory();
    }


    public  SSLSocketFactory getSocketFactory(final String caCrtFile,
                                                    final String crtFile, final String keyFile, final String password)
            throws Exception {

        Security.addProvider(new BouncyCastleProvider());

        // load CA certificate
        X509Certificate caCert = null;


        // FileInputStream fis = new FileInputStream(caCrtFile);
        BufferedInputStream bis = new BufferedInputStream(resourceLoader.getResource(caCrtFile).getInputStream());




        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        while (bis.available() > 0) {
            caCert = (X509Certificate) cf.generateCertificate(bis);
        }

        // load client certificate

        //bis = new BufferedInputStream(new FileInputStream(crtFile));
        bis = new BufferedInputStream(resourceLoader.getResource(crtFile).getInputStream());
        X509Certificate cert = null;
        while (bis.available() > 0) {
            cert = (X509Certificate) cf.generateCertificate(bis);
        }

        // load client private key
//        PEMParser pemParser = new PEMParser(new FileReader(keyFile));
//        Object object = pemParser.readObject();
//        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
//        KeyPair key = converter.getKeyPair((PEMKeyPair) object);
//        pemParser.close();



        // PEMParser pemParser =new PEMParser(new InputStreamReader(new FileInputStream(keyFile)));

        PEMParser pemParser =new PEMParser(new InputStreamReader(resourceLoader.getResource(keyFile).getInputStream()));

        Object obj = pemParser.readObject();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        PrivateKey privateKey = converter.getPrivateKey((PrivateKeyInfo) obj);


        // CA certificate is used to authenticate server
        KeyStore caKs = KeyStore.getInstance(KeyStore.getDefaultType());
        caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
        tmf.init(caKs);

        // client key and certificates are sent to server, so it can authenticate
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", cert);
        ks.setKeyEntry("private-key", privateKey, password.toCharArray(),
                new java.security.cert.Certificate[]{cert});
        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
                .getDefaultAlgorithm());
        kmf.init(ks, password.toCharArray());

        // finally, create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

        return context.getSocketFactory();
    }
}

复制代码

mqq5:

复制代码

package com.lc.common.mqtt.mqttv5;

import cn.hutool.core.util.IdUtil;
import com.lc.common.mqtt.config.MqttConfig;
import com.lc.common.mqtt.utils.SSLUtils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.mqttv5.client.MqttConnectionOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.outbound.Mqttv5PahoMessageHandler;
import org.springframework.integration.mqtt.support.MqttHeaderMapper;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import javax.annotation.Resource;

@Configuration
@Slf4j
public class Mqtt5Client {

    @Resource
    MqttConfig mc;
    @Resource
    private SSLUtils sslUtils;
    @Resource
    private Mqtt5MessageReceiver mqttMessageReceiver;

    /**
     * (生产者) mqtt消息出站通道,用于发送出站消息
     * @return
     */
    @Bean
    public MessageChannel mqttOutputChannel5() {
        return new DirectChannel();
    }

    /**
     * (消费者) mqtt消息入站通道,订阅消息后消息进入的通道。
     * @return
     */
    @Bean
    public MessageChannel mqttInputChannel5() {
        return new DirectChannel();
    }

    public MqttConnectionOptions getOptions() {
        MqttConnectionOptions options = new MqttConnectionOptions();
        options.setServerURIs(mc.getServices());
        options.setUserName(mc.getUser());
        options.setPassword(mc.getPassword().getBytes());
        options.setReceiveMaximum(mc.getMaxInflight());
        options.setKeepAliveInterval(mc.getKeepAliveInterval());
        // 重连设置
        options.setAutomaticReconnect(mc.isAutomaticReconnect());
        options.setMaxReconnectDelay(mc.getMaxReconnectDelay());
        options.setAutomaticReconnectDelay(mc.getV5AutomaticReconnectMinDelay(), mc.getV5AutomaticReconnectMaxDelay());
        // 会话设置
        options.setCleanStart(mc.isV5CleanStart());
        options.setSessionExpiryInterval(mc.getV5SessionExpiryInterval());
        // 超时设置
        options.setConnectionTimeout(mc.getConnectionTimeout());
        try {
            options.setSocketFactory(sslUtils.getSocketFactory(
                    "classpath:ca.pem",
                    "classpath:client.pem",
                    "classpath:client.key",
                    ""));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return options;
    }

    /**
     * 生产者
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttOutputChannel5")
    public MessageHandler mqttOutbound5() {
        String clientId = mc.getV5ProducerId() + "_" + IdUtil.getSnowflakeNextId();;
        Mqttv5PahoMessageHandler messageHandler = new Mqttv5PahoMessageHandler(getOptions(), clientId);
        messageHandler.setHeaderMapper(new MqttHeaderMapper());
        // 设置异步不阻塞
        messageHandler.setAsync(false);
        // 设置Qos
        messageHandler.setDefaultQos(mc.getQos());
        return messageHandler;
    }

    /**
     * MQTT消息订阅绑定(消费者)
     * @return
     */
    @Bean
    public MessageProducer channelInbound5(MessageChannel mqttInputChannel5) {
        String clientId = mc.getV5ConsumerId() + "_" + IdUtil.getSnowflakeNextId();;
        MyMqttv5PahoMessageDrivenChannelAdapter adapter = new MyMqttv5PahoMessageDrivenChannelAdapter(getOptions(), clientId, mc.getV5DefaultTopic());
        adapter.setCompletionTimeout(mc.getCompletionTimeout());
        adapter.setPayloadType(String.class);
        adapter.setQos(mc.getQos());
        adapter.setOutputChannel(mqttInputChannel5);
        return adapter;
    }

    /**
     * MQTT消息处理器(消费者)
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel5")
    public MessageHandler mqttMessageHandler5() {
        return mqttMessageReceiver;
    }
}

复制代码

mqtt3

复制代码

package com.lc.common.mqtt.mqttv3;

import cn.hutool.core.util.IdUtil;
import com.lc.common.mqtt.utils.SSLUtils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import com.lc.common.mqtt.config.MqttConfig;
import javax.annotation.Resource;

@Configuration
@Slf4j
public class Mqtt3Client {
    @Resource
    private MqttConfig mc;

    @Resource
    private SSLUtils sslUtils;

    @Resource
    private Mqtt3MessageReceiver mqttMessageReceiver;

    /**
     * (生产者) mqtt消息出站通道,用于发送出站消息
     * @return
     */
    @Bean
    public MessageChannel mqttOutputChannel3() {
        return new DirectChannel();
    }

    /**
     * (消费者) mqtt消息入站通道,订阅消息后消息进入的通道。
     * @return
     */
    @Bean
    public MessageChannel mqttInputChannel3() {
        return new DirectChannel();
    }

    public MqttConnectOptions getOptions() {
        MqttConnectOptions options = new MqttConnectOptions();
        options.setServerURIs(mc.getServices());
        options.setUserName(mc.getUser());
        options.setPassword(mc.getPassword().toCharArray());
        options.setMaxInflight(mc.getMaxInflight());
        options.setKeepAliveInterval(mc.getKeepAliveInterval());
        // 重连设置
        options.setAutomaticReconnect(mc.isAutomaticReconnect());
        options.setMaxReconnectDelay(mc.getMaxReconnectDelay());
        // options.setAutomaticReconnectDelay(automaticReconnectMinDelay, automaticReconnectMaxDelay);
        // 会话设置
        options.setCleanSession(mc.isV3CleanSession());

        // 超时设置
        options.setConnectionTimeout(mc.getConnectionTimeout());
        // 设置遗嘱消息 qos 默认为 1  retained 默认为 false
        options.setWill("willTopic","与服务器断开连接".getBytes(),0,false);
        try {
            options.setSocketFactory(sslUtils.getSocketFactory(
                    "classpath:ca.pem",
                    "classpath:client.pem",
                    "classpath:client.key",
                    ""));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return options;
    }

    /**
     * 生产者
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttOutputChannel3")
    public MessageHandler mqttOutbound3() {
        String clientId = mc.getV3ProducerId() + "_" + IdUtil.getSnowflakeNextId();
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory() ;
        factory.setConnectionOptions(getOptions());
        MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, factory);
        // 设置异步不阻塞
        messageHandler.setAsync(true);
        // 设置Qos
        messageHandler.setDefaultQos(mc.getQos());
        return messageHandler;
    }

    /**
     * MQTT消息订阅绑定(消费者)
     * @return
     */
    @Bean
    public MessageProducer channelInbound3(MessageChannel mqttInputChannel3) {
        String clientId = mc.getV3ConsumerId() + "_" + IdUtil.getSnowflakeNextId();;
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(getOptions());
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(clientId, factory, mc.getV3DefaultTopic());
        adapter.setCompletionTimeout(mc.getCompletionTimeout());
        adapter.setRecoveryInterval(mc.getV3RecoveryInterval());
        adapter.setConverter(new DefaultPahoMessageConverter());
        adapter.setQos(mc.getQos());
        adapter.setOutputChannel(mqttInputChannel3);
        return adapter;
    }

    /**
     * MQTT消息处理器(消费者)
     * @return
     */
    @Bean
    @ServiceActivator(inputChannel = "mqttInputChannel3")
    public MessageHandler mqttMessageHandler3() {
        return mqttMessageReceiver;
    }
}

复制代码

 0

 0

« 上一篇: SSL/TSL 总结
» 下一篇: npm 错误,ERESOLVE unable to resolve dependency tree 解决方案

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

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

相关文章

Oracle VM VirtualBox仅主机(Host-0nly)网络实现外网连接

目录 1.仅主机(Host-0nly)网络介绍 1.操作步骤 2.测试​编辑 “如果您在解决类似问题时也遇到了困难,希望我的 经验分享 对您有所帮助。如果您有任何疑问或者想分享您的经历,欢迎在评论区留言,我们可以一起探讨解决方案。祝您在编程路上顺利…

通过多模态关系图学习实现可解释的医学图像视觉问答|文献速递--Transformer架构在医学影像分析中的应用

Title 题目 Interpretable medical image Visual Question Answering via multi-modal relationship graph learning 通过多模态关系图学习实现可解释的医学图像视觉问答。 01 文献速递介绍 医学视觉问答(VQA)是医学多模态大语言模型(LL…

通信工程学习:什么是OLT光线路终端

OLT:光线路终端 OLT(Optical Line Terminal,光线路终端)是光纤通信系统中的核心局端设备,特别是在无源光网络(Passive Optical Network, PON)架构中扮演着至关重要的角色。以下是关于OLT光线路终…

GUI编程15:JPanel、JScroll 面板

视频链接:17、文本域JScroll面板_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DJ411B75F?p17&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.JPanel package com.yundait.lesson05;import javax.swing.*; import java.awt.*;public class JPanelDem…

C++速通LeetCode中等第5题-无重复字符的最长字串

字串substr法,定义字串的头部和长度,和字串后一位对比,如果不存在重复元素则长度1,存在重复元素则头部更新,长度重置。 class Solution { public:int lengthOfLongestSubstring(string s) {string s2;//存放s的前一部分…

基于虚拟阻抗的逆变器下垂控制环流抑制策略MATLAB仿真

微❤关注“电气仔推送”获得资料(专享优惠) 模型简介 由于微电网的弱电网特性,变流器并网线路较大的阻感比会导致变流器输出功率不能近似解耦,从而影响其下垂控制的精度。另外变流器并网线路阻抗的不确定性还会导致变流器之间分…

放过自己,决绝内耗

其实真正折磨你的,从来不是任何人的绝情,也不是糟糕的事情,而是你心存幻想的期待和无法控制的想象力,很多时候,你不是过不去生活的那道坎,而是过不了你心里的那一关,世间万物都在治愈你&#xf…

深入探究 Flask 的应用和请求上下文

目标 读完本文后,您应该能够解释: 什么是上下文哪些数据同时存储在应用程序和请求上下文中在 Flask 中处理请求时,处理应用程序和请求上下文所需的步骤如何使用应用程序和请求上下文的代理如何在视图函数中使用current_app和代理request什么…

『功能项目』第三职业弓弩的平A【58】

我们打开上一篇57第二职业法师的平A的项目, 本章要做的事情是实现第三职业弓弩的平A伤害 首先修改脚本:MagicBall.cs 将脚本挂载在Sphere预制体身上 注意组件设置 运行项目 本章做了第三职业弓弩的平A伤害及显示伤害UI 接下来文章的内容: …

【深度学习】(1)--神经网络

文章目录 深度学习神经网络1. 感知器2. 多层感知器偏置 3. 神经网络的构造4. 模型训练损失函数 总结 深度学习 深度学习(DL, Deep Learning)是机器学习(ML, Machine Learning)领域中一个新的研究方向。 从上方的内容包含结果,我们可以知道,在学习深度学…

你真的需要理解Diffusion(扩散模型),它在视觉领域具有无与伦比的美丽!

【Vision结合Diffusion】模型的研究方向,探索了如何利用扩散模型在数据空间中模拟随机游走的特性,以生成高质量和逼真的图像。这一领域的研究,通过结合视觉感知和文本描述,推动了图像合成技术的发展,尤其是在个性化图像…

家用小型洗衣机哪个牌子好?五款热搜爆火型号,速来围观

在日常生活中,内衣洗衣机已成为现代家庭必备的重要家电之一。选择一款耐用、质量优秀的内衣洗衣机,不仅可以减少洗衣负担,还能提供高效的洗涤效果。然而,市场上众多内衣洗衣机品牌琳琅满目,让我们往往难以选择。那么&a…

LabVIEW提高开发效率技巧----使用事件结构优化用户界面响应

事件结构(Event Structure) 是 LabVIEW 中用于处理用户界面事件的强大工具。通过事件驱动的编程方式,程序可以在用户操作时动态执行特定代码,而不是通过轮询(Polling)的方式不断检查界面控件状态。这种方式…

C++速通LeetCode中等第8题-最大字数组和

class Solution { public:int maxSubArray(vector<int>& nums) {if(nums.size()1) return nums[0];vector<int> v;int sum 0;for(int i 0;i < nums.size();i){sum nums[i];v.push_back(sum);}//结合股票最大利益那题int ans -10000;int lowest v[0];fo…

【毕设】基于Java的超市管理系统

基于Java的超市管理系统是一个用于管理超市日常运营的软件解决方案&#xff0c;它可以包括库存管理、销售管理、客户管理等多个模块。以下是一个简化的系统设计方案&#xff0c;以及一些关键组件和技术选型的建议。 系统架构 前端&#xff1a; HTML/CSS/JavaScript&#xf…

JavaDS —— B树

前言 本章节将带领大家进入B树的学习&#xff0c;主要介绍B树的概念和B树的插入代码的实现&#xff0c;删除代码不做讲解&#xff0c;最后简单介绍B树和B*树。 B树的概念 1970年&#xff0c;R.Bayer和E.mccreight提出了一种适合外查找的树&#xff0c;它是一种平衡的多叉树&…

裸土覆盖检测算法、裸土识别检测算法、裸土检测算法

裸土检测算法是一种基于计算机视觉和图像处理技术&#xff0c;用于自动识别和评估裸露土壤区域的智能工具。以下是对裸土检测算法的详细介绍&#xff1a; 1. 技术原理 - 数据采集与预处理&#xff1a;利用卫星、无人机或传感器收集地面图像数据&#xff0c;并进行必要的预处理…

练完这些项目,你就是大模型大师!

去年侧重大模型和GPT的原理&#xff0c;今年就侧重项目实战了。找到的这个合集不仅收集了大模型训练实战&#xff0c;还有微调实战&#xff0c;分布式训练&#xff0c;真的很全。 github项目名llm-action 本项目旨在分享大模型相关技术原理以及实战经验。 这份《大模型项目集》…

【Python爬虫】学习Python必学爬虫,这篇文章带您了解Python爬虫,Python爬虫详解!!!

Python爬虫详解 Python爬虫是一种用于从网站获取数据的自动化脚本。它使用Python编程语言编写&#xff0c;并利用各种库和模块来实现其功能。以下是Python爬虫的详细讲解&#xff0c;包括基本概念、常用库、基本流程和示例代码。 基本概念 HTTP请求&#xff1a;爬虫通过向目…

Docker部署及基本操作

Docker是一个开源的平台 &#xff0c;用于开发、交付和运行应用程序。它能够在Windows&#xff0c;macOS&#xff0c;Linux计算机上运行&#xff0c;并将某一应用程序及其依赖项打包至一个容器中&#xff0c;这些容器可以在任何支持Docker的环境中运行。容器彼此隔离&#xff0…