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

openssl 生成多域名 多IP 的数字证书的更多相关文章

  1. openssl生成iis需要的pfx格式的证书

    合成.pfx证书 将私钥文件(server.key)和服务器crt证书文件(server.crt ),放到openssl安装目录的bin目录下. 控制台也进到此目录下,然后执行下面指令. openss ...

  2. [openssl] 使用openssl生成证书

    使用openssl生成带域名的证书,SAN,subjectAltName, subject alternative name, DNS. 1. 生成私钥 openssl genrsa - 2. 编写配 ...

  3. 免费CA数字证书的申请、安装、导入、导出

    http://wenku.baidu.com/link?url=oDUw50eCE5zX8tmg4N3-ddYGLt1U5aJYGEN7rk_z7t6LuMHL3M4oBstYBI_dQ1UnCtcK ...

  4. 公私钥 SSH 数字证书

    公私钥 SSH 数字证书 小菜鸟今天买了华为云一台服务器,在使用公私钥远程登录服务器的时候,忘记了相关公钥私钥的原理和一些应用了,今天复习一波做个记录. 相关概念 公钥:公钥用来给数据加密,用公钥加密 ...

  5. 用Keytool和OpenSSL生成和签发数字证书

    一)keytool生成私钥文件(.key)和签名请求文件(.csr),openssl签发数字证书      J2SDK在目录%JAVA_HOME%/bin提供了密钥库管理工具Keytool,用于管理密 ...

  6. OpenSSL生成公钥私钥***

    证书标准 X.509 - 这是一种证书标准,主要定义了证书中应该包含哪些内容.其详情可以参考RFC5280,SSL使用的就是这种证书标准. 编码格式 同样的X.509证书,可能有不同的编码格式,目前有 ...

  7. Golang(十一)TLS 相关知识(二)OpenSSL 生成证书

    0. 前言 接前一篇文章,上篇文章我们介绍了数字签名.数字证书等基本概念和原理 本篇我们尝试自己生成证书 参考文献:TLS完全指南(二):OpenSSL操作指南 1. OpenSSL 简介 OpenS ...

  8. OpenSSL - 网络安全之数据加密和数字证书

    功能应用: 消息摘要,给文件或数据生成消息摘要,消息摘要只能校验数据的完整性,如SHA.MD5 数据加密和解密:对数据进行加密解密,OpenSSL实现了所有加密算法 数字证书:可以通过命令行或代码生成 ...

  9. IIS 使用OpenSSL 生成的自签名证书,然后使用SingalR 客户端访问Https 站点通信

    使用SignalR 的客户端去发送消息给使用 https 部署的站点,官方文档目前并没有详细的教程,所以在此记录下步骤: 使用管理员身份打开cmd 窗口,选择一个整数保存文件夹的地址,切换到对应的文件 ...

  10. OPENSSL生成SSL自签证书

    OPENSSL生成SSL自签证书 目前,有许多重要的公网可以访问的网站系统(如网银系统)都在使用自签SSL证书,即自建PKI系统颁发的SSL证书,而不是部署支持浏览器的SSL证书. 支持浏览器的SSL ...

随机推荐

  1. 【FAQ】HarmonyOS SDK 闭源开放能力 —IAP Kit

    1.问题描述 根据https://developer.huawei.com/consumer/cn/doc/harmonyos-references/iap-data-model-0000001736 ...

  2. spark dstaframe 多字段统计

    val aggCols = List("Pclass","Age","Fare") .map(colName=>functions.a ...

  3. Web 在线制表工具稳定吗?和桌面报表工具对比哪个好用?

    报表工具中最成熟常用的基本都是桌面设计器,但是 web 在线制表工具也占有部分市场,这是因为它也有一些优点: 1.报表设计和发布都在 web 端,无需额外安装桌面设计器 2.web 在线制表工具可直接 ...

  4. 鸿蒙HarmonyOS实战-ArkUI动画(布局更新动画)

    前言 动画是一种通过连续展示一系列静止的图像(称为帧)来创造出运动效果的艺术形式.它可以以手绘.计算机生成或其他各种形式呈现.在动画中,每一帧都具有微小的变化,当这些帧被快速播放时,人眼会产生视觉上的 ...

  5. 企业实施定制鞋厂ERP软件需要注意哪些问题?

    企业实施定制ERP软件是个复杂的管理系统工程,为了成功地为企业定制实施ERP软件,需要注意和解决几个关键的问题: (1) . 确立ERP系统实施和定制的决策者: (2) . 做好前期咨询与调研工作: ...

  6. Fluid — 云原生环境下的高效“数据物流系统”

    简介: 为了解决大数据.AI 等数据密集型应用在云原生计算存储分离场景下,存在的数据访问延时高.联合分析难.多维管理杂等痛点问题,南京大学 PASALab.阿里巴巴.Alluxio 在 2020 年 ...

  7. 十年再出发,Dubbo 3.0 Preview 即将在 3 月发布

    ​简介:随着Dubbo和HSF的整合,我们在整个开源的体系中更多地去展现了 HSF 的能力,能够让更多的人通过使用 Dubbo 像阿里巴巴之前使用 HSF 一样更好的构建服务化的系统. 2011 年, ...

  8. 开源微服务编排框架:Netflix Conductor

    简介:本文主要介绍netflix conductor的基本概念和主要运行机制. ​ 作者 | 夜阳 来源 | 阿里技术公众号 本文主要介绍netflix conductor的基本概念和主要运行机制. ...

  9. [FAQ] FinalCutPro 视频背景加模糊效果

    1. 时间轴右上方,找到 倒数第二个 "显示或隐藏效果浏览器",里面有一个 "模糊" 效果: 2. "模糊"效果中的 "高斯曲线& ...

  10. 扎克伯格说,Llama3-8B还是太大了,量化、剪枝、蒸馏准备上!

    扎克伯格说,Llama3-8B还是太大了,不适合放到手机中,有什么办法? 量化.剪枝.蒸馏,如果你经常关注大语言模型,一定会看到这几个词,单看这几个字,我们很难理解它们都干了些什么,但是这几个词对于现 ...