win10系统下openssl证书生成和单向认证

2024-09-07 13:20

本文主要是介绍win10系统下openssl证书生成和单向认证,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、安装openssl
  • 二、创建证书目录和必要文件
    • 1、创建sslcertTest文件夹
    • 2、创建openssl.cnf文件
    • 3、创建必要文件
  • 三、创建密钥和证书
    • 1、创建根证书私钥ca.key
    • 2、创建根证书请求文件ca.csr
    • 3、创建自签根证书ca.crt
    • 4、创建服务端私钥server.key
    • 5、创建服务端证书请求文件server.csr
    • 6、创建自签服务端证书server.crt
  • 四、Qt使用QSslSocket实现的单向认证
    • 1、客户端
    • 2、服务端


前言

最近工作中要完成ssl加密啊通信,使用到了openssl,本文主要介绍win10系统下其安装和配置及对应的密钥和证书的生成步骤.

一、安装openssl

下载Win64OpenSSL-1_1_1,双击安装;配置环境变量,如下:
在这里插入图片描述
验证是否安装成功,输入如下命令:

openssl version

在这里插入图片描述

二、创建证书目录和必要文件

1、创建sslcertTest文件夹

我是在C盘下创建的该文件夹.

2、创建openssl.cnf文件

在sslcertTest文件夹下,创建openssl.cnf文件,设置系统变量:
在这里插入图片描述

3、创建必要文件

在sslcertTest文件夹下,创建demoCA文件夹;在该文件夹下,创建index.txt、database.txt、serial文件和newcerts文件夹;其中,serial文件创建后,打开该文件并在第一行编辑输入01
在这里插入图片描述

三、创建密钥和证书

1、创建根证书私钥ca.key

在C:\sslcertTest目录下,进入命令行,命令如下:

openssl genrsa -out ca.key 2048

此命令采用无密码模式,genrsa 表示采用RSA算法生成根证书私钥,2048表示根证书私钥长度,越长越安全.

2、创建根证书请求文件ca.csr

命令如下:

openssl req -new -key ca.key -out ca.csr

以下为demo:

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:TJ
Locality Name (eg, city) []:TJ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:TJ
Organizational Unit Name (eg, section) []:TJ
Common Name (e.g. server FQDN or YOUR name) []:192.168.10.254
Email Address []:

其中,Country Name 必须填写CN,Common Name 填写服务器IP或域名,否则监测器使用过程中会报SSL错误,尽管忽略错误后可以完成通信。Email Address可以不填;

3、创建自签根证书ca.crt

命令如下:

openssl x509 -req -in ca.csr -signkey ca.key -out ca.crt -days 3650

此处是使用openssl命令完成自签名,证书格式x509,证书有效期10年。

4、创建服务端私钥server.key

命令如下:

openssl genrsa -out server.key 2048

5、创建服务端证书请求文件server.csr

命令如下:

openssl req -new -key server.key -out server.csr

输入如下:

Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:TJ
Locality Name (eg, city) []:TJ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:TJ
Organizational Unit Name (eg, section) []:TJ
Common Name (e.g. server FQDN or YOUR name) []:192.168.10.254
Email Address []:

注意此处,与CA证书请求文件输入一致。

6、创建自签服务端证书server.crt

命令如下:

openssl ca -in server.csr -cert ca.crt -keyfile ca.key -out server.crt -days 3650

此处是自签名,即使用上述自己创建的ca.crt和ca.key,对server.csr进行签名,最终生成一个带有签名的server.crt。
如果你的服务端证书需要别的CA签名机构来签名,则将server.csr请求文件发送给签名机构,签名过程中需要CA的公钥证书和私钥参与,机构签名完成后,返回一个带有CA签名的server.crt文件。
在这里插入图片描述

四、Qt使用QSslSocket实现的单向认证

这里仅展示主要代码:

1、客户端

#include "certificateinfo.h"
#include "sslclient.h"SslClient::SslClient(QWidget *parent): QWidget(parent)
{setupUi();setupSecureSocket();
}SslClient::~SslClient()
{}void SslClient::updateEnabledState()
{/* 不为空或socket处于未连接状态,则unconnected为真 */const bool unconnected = socket->state() == QAbstractSocket::UnconnectedState;/* 更新界面各控件的状态 */hostNameEdit->setReadOnly(!unconnected);hostNameEdit->setFocusPolicy(unconnected ? Qt::StrongFocus : Qt::NoFocus);hostNameLabel->setEnabled(unconnected);portBox->setEnabled(unconnected);portLabel->setEnabled(unconnected);connectButton->setEnabled(unconnected && !hostNameEdit->text().isEmpty());const bool connected = socket->state() == QAbstractSocket::ConnectedState;sessionOutput->setEnabled(connected);sessionInput->setEnabled(connected);sessionInputLabel->setEnabled(connected);sendButton->setEnabled(connected);
}/* 点击connect按钮后会执行该函数 */
void SslClient::secureConnect()
{/* 设置SSL协议版本,和服务器相同 */socket->setProtocol(QSsl::TlsV1_2);/* 由于是自签证,所以要设置根证书,用于验证服务器证书,否则客户端不信任服务器 */QList<QSslCertificate> certs = QSslCertificate::fromPath("C:/sslcertTest/ca.crt");socket->setCaCertificates(certs);/* 客户端链接服务器进行SSL握手,当进入加密模式后会发出Encrypted()信号 */socket->connectToHostEncrypted(hostNameEdit->text(), portBox->value());updateEnabledState();
}void SslClient::socketStateChanged(QAbstractSocket::SocketState state)
{if (executingDialog)return;updateEnabledState();if (state == QAbstractSocket::UnconnectedState) {sessionInput->clear();hostNameEdit->setPalette(QPalette());hostNameEdit->setFocus();cipherLabel->setText(tr("<无>"));padLock->hide();}
}void SslClient::socketEncrypted()
{sessionOutput->clear();sessionInput->setFocus();/* 设置lineEdit的背景色 */QPalette palette;palette.setColor(QPalette::Base, QColor(255, 255, 192));hostNameEdit->setPalette(palette);/* 显示加密算法种类 */const QSslCipher cipher = socket->sessionCipher();const QString cipherInfo = QString("%1, %2 (%3/%4)").arg(cipher.authenticationMethod()).arg(cipher.name()).arg(cipher.usedBits()).arg(cipher.supportedBits());cipherLabel->setText(cipherInfo);padLock->show();
}/* 读取数据 */
void SslClient::socketReadyRead()
{appendString(QString::fromUtf8(socket->readAll()));
}/* 发送数据 */
void SslClient::sendData()
{const QString input = sessionInput->text();appendString(input + '\n');socket->write(input.toUtf8() + "\r\n");sessionInput->clear();
}void SslClient::socketError(QAbstractSocket::SocketError)
{if (handlingSocketError)return;handlingSocketError = true;QMessageBox::critical(this, tr("连接错误"), socket->errorString());handlingSocketError = false;
}void SslClient::sslErrors(const QList<QSslError> &errors)
{sslerror->clearError();for (const auto &error : errors)sslerror->showError(error.errorString());executingDialog = true;if (sslerror->exec() == QDialog::Accepted)socket->ignoreSslErrors();executingDialog = false;// did the socket state change?if (socket->state() != QAbstractSocket::ConnectedState)socketStateChanged(socket->state());
}/* 弹出证书内容显示窗口 */
void SslClient::displayCertificateInfo()
{CertificateInfo info;info.setCertificateChain(socket->peerCertificateChain());info.exec();
}void SslClient::setupUi()
{gridLayout = new QGridLayout;hostNameEdit = new QLineEdit;hostNameLabel = new QLabel;portBox = new QSpinBox;portLabel = new QLabel;sessionLayout = new QHBoxLayout;label = new QLabel;connectButton = new QPushButton;labelLayout = new QHBoxLayout;cipherLabel = new QLabel;cipherText = new QLabel;sessionOutput = new QTextEdit;inputLayout = new QHBoxLayout;sendButton = new QPushButton;sessionInput = new QLineEdit;sessionInputLabel = new QLabel;mainLayout = new QVBoxLayout;hostNameLabel->setText("主机名称:");portLabel->setText("端口:");hostNameEdit->setText("192.168.3.140");portBox->setRange(0,65535);portBox->setValue(5001);gridLayout->addWidget(hostNameLabel,0,0);gridLayout->addWidget(hostNameEdit,0,1);gridLayout->addWidget(portLabel,1,0);gridLayout->addWidget(portBox,1,1);label->setText("激活会话");connectButton->setText("连接到主机");sessionLayout->addWidget(label);sessionLayout->addWidget(connectButton);cipherLabel->setText("<加密算法>");cipherText->setText("<无>");labelLayout->addWidget(cipherLabel);labelLayout->addStretch();labelLayout->addWidget(cipherText);sessionInputLabel->setText("输入:");sendButton->setText("发送");inputLayout->addWidget(sessionInputLabel);inputLayout->addWidget(sessionInput);inputLayout->addWidget(sendButton);hostNameEdit->setSelection(0, hostNameEdit->text().size());sessionOutput->setHtml(tr("&lt;无连接&gt;"));mainLayout->addLayout(gridLayout);mainLayout->addLayout(sessionLayout);mainLayout->addLayout(labelLayout);mainLayout->addWidget(sessionOutput);mainLayout->addLayout(inputLayout);setLayout(mainLayout);connect(hostNameEdit, SIGNAL(textChanged(QString)),this, SLOT(updateEnabledState()));connect(connectButton, SIGNAL(clicked()),this, SLOT(secureConnect()));connect(sendButton, SIGNAL(clicked()),this, SLOT(sendData()));sslerror = new SslErrors;connect(sslerror,&SslErrors::sigDisplayCertificateInfo,this,&SslClient::displayCertificateInfo);setWindowTitle("SSL通信客户端");padLock = new QToolButton;/* 设置按钮图标 */padLock->setIcon(QIcon(":/encrypted.png"));connect(padLock, SIGNAL(clicked()), this, SLOT(displayCertificateInfo()));#if QT_CONFIG(cursor)padLock->setCursor(Qt::ArrowCursor);
#endif/* 设置提示信息 */padLock->setToolTip(tr("显示详细加密信息."));/* 调整按钮大小和焦点 */const int extent = hostNameEdit->height() - 2;padLock->resize(extent, extent);padLock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);/* 界面布局 */QHBoxLayout *layout = new QHBoxLayout(hostNameEdit);layout->setMargin(hostNameEdit->style()->pixelMetric(QStyle::PM_DefaultFrameWidth));layout->setSpacing(0);layout->addStretch();layout->addWidget(padLock);hostNameEdit->setLayout(layout);padLock->hide();resize(300,300);
}void SslClient::setupSecureSocket()
{/* socket为空则创建 */if (socket)return;socket = new QSslSocket(this);connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));connect(socket, SIGNAL(encrypted()),this, SLOT(socketEncrypted()));connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(socketError(QAbstractSocket::SocketError)));connect(socket, SIGNAL(sslErrors(QList<QSslError>)),this, SLOT(sslErrors(QList<QSslError>)));connect(socket, SIGNAL(readyRead()),this, SLOT(socketReadyRead()));
}void SslClient::appendString(const QString &line)
{/* 设置光标 */QTextCursor cursor(sessionOutput->textCursor());cursor.movePosition(QTextCursor::End);cursor.insertText(line);/* 将滚动条设置到最后一行 */sessionOutput->verticalScrollBar()->setValue(sessionOutput->verticalScrollBar()->maximum());
}

2、服务端

#include "sslserver.h"
#include <QDebug>
#include <QThread>
#include <QMessageBox>sslserver::sslserver(QObject *parent) : QTcpServer(parent)
{
}sslserver::~sslserver()
{
}/* 当有客户端连接上服务器时会调用该函数 */
void sslserver::incomingConnection(qintptr socketDescriptor)
{sock = new QSslSocket;connect(sock,SIGNAL(readyRead()),this,SLOT(readyRead()));connect(sock,SIGNAL(encrypted()),this,SLOT(encrypted()));/* 设置根证书,握手时客户端会接收到根证书 QList<QSslCertificate> certs = QSslCertificate::fromPath("C:/sslcertTest/ca.crt");sock->setCaCertificates(certs);*//* 设置本地的服务器证书,证书中的Common Name要写服务器地址 */sock->setLocalCertificate("C:/sslcertTest/server.crt");/* 当服务器秘钥有密码时 *///QString passwd = "1234";//sock->setPrivateKey("C:/sslcertTest/server.key",QSsl::Rsa,QSsl::Pem,passwd.toLocal8Bit());/* 如果服务器秘钥没有密码 */sock->setPrivateKey("C:/sslcertTest/server.key");/* 设置ssl通信协议版本 */sock->setProtocol(QSsl::TlsV1_2);/* 使用的加密算法 *//* 默认就是这个"DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA" */sock->setCiphers(QSslSocket::supportedCiphers());//sock->setCiphers("RC4-SHA");if(sock->setSocketDescriptor(socketDescriptor)){/* SSL握手 */sock->startServerEncryption();}else{delete sock;}
}void sslserver::startssl()
{/* 允许所有地址,监听端口5001,设置这个端口为了排除其他的干扰*/listen(QHostAddress::Any,5001);  //
}void sslserver::readyRead()
{if(display){display->append(sock->readAll());}
}void sslserver::encrypted()
{if(display){display->append("进入加密模式");}
}void sslserver::setDisplayContrl(QTextEdit *disp)
{display = disp;
}

这篇关于win10系统下openssl证书生成和单向认证的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145172

相关文章

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];