网站建设公司能信吗,自动化系统网站建设首选公司,品牌创建和品牌建设区别,宁波宣传片制作公司文章目录 前言一、安装openssl二、创建证书目录和必要文件1、创建sslcertTest文件夹2、创建openssl.cnf文件3、创建必要文件 三、创建密钥和证书1、创建根证书私钥ca.key2、创建根证书请求文件ca.csr3、创建自签根证书ca.crt4、创建服务端私钥server.key5、创建服务端证书请求文… 文章目录 前言一、安装openssl二、创建证书目录和必要文件1、创建sslcertTest文件夹2、创建openssl.cnf文件3、创建必要文件 三、创建密钥和证书1、创建根证书私钥ca.key2、创建根证书请求文件ca.csr3、创建自签根证书ca.crt4、创建服务端私钥server.key5、创建服务端证书请求文件server.csr6、创建自签服务端证书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 必须填写CNCommon 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 20485、创建服务端证书请求文件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.hSslClient::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);/* 由于是自签证所以要设置根证书用于验证服务器证书否则客户端不信任服务器 */QListQSslCertificate 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 QListQSslError 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(QListQSslError)),this, SLOT(sslErrors(QListQSslError)));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 QMessageBoxsslserver::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()));/* 设置根证书握手时客户端会接收到根证书 QListQSslCertificate 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;
}