当前位置: 首页 > news >正文

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

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.Resourceprivate  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 certificateX509Certificate 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 serverKeyStore 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 authenticateKeyStore 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 factorySSLContext 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 {@ResourceMqttConfig mc;@Resourceprivate SSLUtils sslUtils;@Resourceprivate Mqtt5MessageReceiver mqttMessageReceiver;/*** (生产者) mqtt消息出站通道,用于发送出站消息* @return*/@Beanpublic MessageChannel mqttOutputChannel5() {return new DirectChannel();}/*** (消费者) mqtt消息入站通道,订阅消息后消息进入的通道。* @return*/@Beanpublic 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);// 设置QosmessageHandler.setDefaultQos(mc.getQos());return messageHandler;}/*** MQTT消息订阅绑定(消费者)* @return*/@Beanpublic 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 {@Resourceprivate MqttConfig mc;@Resourceprivate SSLUtils sslUtils;@Resourceprivate Mqtt3MessageReceiver mqttMessageReceiver;/*** (生产者) mqtt消息出站通道,用于发送出站消息* @return*/@Beanpublic MessageChannel mqttOutputChannel3() {return new DirectChannel();}/*** (消费者) mqtt消息入站通道,订阅消息后消息进入的通道。* @return*/@Beanpublic 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 默认为 falseoptions.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);// 设置QosmessageHandler.setDefaultQos(mc.getQos());return messageHandler;}/*** MQTT消息订阅绑定(消费者)* @return*/@Beanpublic 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.lryc.cn/news/440413.html

相关文章:

  • 电影评论|基于springBoot的电影评论网站设计与实现(附项目源码+论文+数据库)
  • 【C++】虚函数
  • esxi虚拟机启用cbt备份(增量备份)
  • mysql 8.0 时间维度表生成(可运行)
  • 打造高效实时数仓,从Hive到OceanBase的经验分享
  • 15.3 JDBC数据库编程
  • SSH公私钥后门从入门到应急响应
  • 服务器数据恢复—Linux操作系统环境下网站数据的恢复案例
  • 开放式耳机是怎么样的?开放式耳机的优缺点分析?
  • HDMI色块移动——FPGA学习笔记13
  • MySQL中去除重复
  • 【C++】vector容器的基本使用
  • 【强化学习系列】Gym库使用——创建自己的强化学习环境2:拆解官方标准模型源码/规范自定义类+打包自定义环境
  • PyQt5实现按钮选择文件夹及文件夹
  • Gin渲染
  • 前端——JS基础
  • MATLAB入门教程
  • muduo - 概要简述
  • Selenium点击元素的方法
  • kali里面搭建docker容器
  • WebGL系列教程八(GLSL着色器基础语法)
  • go多线程
  • 【话题】如何看待IBM中国研发部裁员?
  • 【C/C++】涉及string类的经典OJ编程题
  • 淘系等电商平台API接口系列:商品详情数据解析,json数据返回参考
  • vue组件之间的数据共享
  • LangChain:构建强大的LLM应用的全方位框架
  • 自有平台自有品牌如何利用电商API接口做定价参考(多平台商品详情数据接口)
  • 三万字长文Java面试题——基础篇(注:该篇博客将会一直维护 最新维护时间:2024年9月18日)
  • 数学建模——熵权+TOPSIS+肘部法则+系统聚类