Qt使用OpenSSL

https://github.com/mygit03/MySSL.git


MySSL.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-06-29T14:23:26
#
#-------------------------------------------------

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = MySSL
TEMPLATE = app


SOURCES += main.cpp\
        myssl.cpp

HEADERS  += myssl.h

FORMS    += myssl.ui


LIBS += -L"C:/OpenSSL-Win32/bin" -llibeay32
LIBS += -L"C:/OpenSSL-Win32/bin" -lssleay32

INCLUDEPATH += $$quote(C:/OpenSSL-Win32/include)

myssl.cpp

#include "myssl.h"
#include "ui_myssl.h"

#include <QDebug>
#include <openssl/ssl.h>
#include <openssl/aes.h>
#include <QSqlQuery>
#include <QSqlError>
#include <QMessageBox>

#define AES_BITS 128
#define MSG_LEN 128

char key[AES_BLOCK_SIZE];
char sourceStringTemp[MSG_LEN];
char dstStringTemp[MSG_LEN];

MySSl::MySSl(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MySSl)
{
    ui->setupUi(this);

    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName("openssl.db");
    if(m_db.open())
    {
        qDebug()<<"m_db Opened";

        QSqlQuery sql_query;
        QString create_sql = "create table if not exists info (src varchar(30) primary key, dst varchar(30), key varchar(30))"; //创建数据表
//        QString insert_sql = "insert into info values(?,?,?)";    //插入数据
//        QString select_all_sql = "select * from info";

        sql_query.prepare(create_sql); //创建表
        if(!sql_query.exec()) //查看创建表是否成功
        {
            qDebug()<<QObject::tr("Table Create failed");
            qDebug()<<sql_query.lastError();
        }
        else
        {
            qDebug()<< "Table Created" ;

            //插入数据
//            sql_query.prepare(insert_sql);

//            QVariantList GroupIDs;
//            GroupIDs.append("0");
//            GroupIDs.append("1");
//            GroupIDs.append("2");

//            QVariantList GroupNames;
//            GroupNames.append("hsp");
//            GroupNames.append("rl");
//            GroupNames.append("spl");

//            QVariantList GroupAddress;
//            GroupAddress.append("南充");
//            GroupAddress.append("宝鸡");
//            GroupAddress.append("南充");

//            sql_query.addBindValue(GroupIDs);
//            sql_query.addBindValue(GroupNames);
//            sql_query.addBindValue(GroupAddress);

//            if(!sql_query.execBatch())
//            {
//                qDebug()<<sql_query.lastError();
//            }
//            else
//            {
//                qDebug()<<"插入记录成功";
//            }

//            //查询所有记录
//            sql_query.prepare(select_all_sql);
//            if(!sql_query.exec())
//            {
//                qDebug()<<sql_query.lastError();
//            }
//            else
//            {
//                while(sql_query.next())
//                {
//                    int id = sql_query.value(0).toInt();
//                    QString name = sql_query.value(1).toString();
//                    QString address = sql_query.value(2).toString();
//                    qDebug()<<QString("ID:%1  Name:%2  Address:%3").arg(id).arg(name).arg(address);
//                }
//            }
        }
    }
    m_db.close();
}

MySSl::~MySSl()
{
    delete ui;
}

//加密
std::string MySSl::sha256(const std::string str)
{
    char buf[2];
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, str.c_str(), str.size());
    SHA256_Final(hash, &sha256);
    std::string newString = "";
    for(int i = 0; i < SHA256_DIGEST_LENGTH; i++)
    {
        sprintf(buf,"%02x",hash[i]);
        newString = newString + buf;
    }
    return newString;
}

//加密
int MySSl::aes_encrypt(char* in, char* key, char* out)//, int olen)可能会设置buf长度
{
    if(!in || !key || !out) return 0;
    unsigned char iv[AES_BLOCK_SIZE];//加密的初始化向量
    for(int i=0; i<AES_BLOCK_SIZE; ++i)//iv一般设置为全0,可以设置其他,但是加密解密要一样就行
        iv[i]=0;
    AES_KEY aes;
    if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len=strlen(in);//这里的长度是char*in的长度,但是如果in中间包含'\0'字符的话

    //那么就只会加密前面'\0'前面的一段,所以,这个len可以作为参数传进来,记录in的长度

    //至于解密也是一个道理,光以'\0'来判断字符串长度,确有不妥,后面都是一个道理。
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_ENCRYPT);

    return 1;
}

//解密
int MySSl::aes_decrypt(char* in, char* key, char* out)
{
    if(!in || !key || !out) return 0;
    unsigned char iv[AES_BLOCK_SIZE];//加密的初始化向量
    for(int i=0; i<AES_BLOCK_SIZE; ++i)//iv一般设置为全0,可以设置其他,但是加密解密要一样就行
        iv[i]=0;
    AES_KEY aes;
    if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
    {
        return 0;
    }
    int len=strlen(in);
    AES_cbc_encrypt((unsigned char*)in, (unsigned char*)out, len, &aes, iv, AES_DECRYPT);
    return 1;
}

void MySSl::openDB()
{
    if(m_db.open()){
        qDebug() << "m_db open success!";
    }else{
        qDebug() << "m_db open fail!";
    }
}

void MySSl::closeDB()
{
    m_db.close();
}

void MySSl::on_btn_encry_clicked()
{
#if 0
    QString tmp = ui->textEdit->toPlainText();
    std::string str = tmp.toStdString();
    qDebug() << "str:" << tmp;
    std::string encryStr = sha256(str);
    qDebug() << QString::fromStdString(encryStr);
    ui->textEdit_2->setText(QString::fromStdString(encryStr));
#else
    QString tmp,str;
    memset((char*)sourceStringTemp, 0 ,MSG_LEN);
    memset((char*)dstStringTemp, 0 ,MSG_LEN);
    QString text = ui->textEdit->toPlainText();
    strcpy((char*)sourceStringTemp, text.toLatin1().data());

//    for(int i = 0; i < 16; ++i)//可自由设置密钥
//    {
//        key[i] = 32 + i;
//    }

    QString iKey = ui->lineEdit->text();
    if(iKey.isEmpty()){
        QMessageBox::warning(this,tr("警告:"),tr("密钥为空!"));
        return;
    }
    strcpy((char*)key, iKey.toLatin1().data());

    //加密
    if(!aes_encrypt(sourceStringTemp,key,dstStringTemp))
    {
        printf("encrypt error\n");
        return;
    }
    printf("enc %d:",strlen((char*)dstStringTemp));
    for(int i = 0; dstStringTemp[i]; ++i){
        printf("%x",(unsigned char)dstStringTemp[i]);
        tmp.sprintf("%x",(unsigned char)dstStringTemp[i]);
        str.append(tmp);
    }
    qDebug() << "dfaf:" << str;
    ui->textEdit_2->setText(tr("<font size=5 color=red>%1</font>").arg(str));

    QString src = ui->textEdit->toPlainText();
    QString dst = dstStringTemp;

    openDB();
    QSqlQuery qry(m_db);
    QString strSql = QString("insert into info values ('%1','%2','%3')").arg(src).arg(dst).arg(iKey);
    if(!qry.exec(strSql)){
        qDebug() << "insert:" << qry.lastError();
    }
    closeDB();
#endif
}

void MySSl::on_textEdit_textChanged()
{
    ui->textEdit_2->clear();
}

void MySSl::on_btn_decry_clicked()
{
    QString iKey = ui->lineEdit->text();
    if(iKey.isEmpty()){
        QMessageBox::warning(this,tr("警告:"),tr("密钥为空!"));
        return;
    }
    QString strSql = QString("select * from info where key='%1'").arg(iKey);
    openDB();
    QSqlQuery qry(m_db);
    if(!qry.exec(strSql)){
        qDebug() << qry.lastError();
        return;
    }
    QString src,dst;
    if (qry.next()) {
        src = qry.value(0).toString();
        dst = qry.value(1).toString();
    }
    qDebug() << "fsdadsf:" << src << dst << iKey;

    //解密
    strcpy((char*)key,iKey.toLatin1().data());
    memset((char*)sourceStringTemp, 0 ,MSG_LEN);
    if(!aes_decrypt(dstStringTemp,key,sourceStringTemp))
    {
        printf("decrypt error\n");
        return;
    }
    printf("\n");
    printf("dec %d:",strlen((char*)sourceStringTemp));
    printf("%s\n",sourceStringTemp);
    ui->textEdit_3->setText(sourceStringTemp);
    for(int i = 0; sourceStringTemp[i]; ++i){
        printf("%x",(unsigned char)sourceStringTemp[i]);
    }
    printf("\n");
}



参考教程:

Qt之OpenSSL

openssl之aes加密(源码分析 AES_encrypt 与 AES_cbc_encrypt ,加密模式)

openssl之aes加密(AES_cbc_encrypt 与 AES_encrypt 的编程案例)









  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt使用OpenSSL,可以通过以下步骤实现: 1. 下载OpenSSL库 可以从OpenSSL官网下载最新版本的OpenSSL库,也可以使用系统自带的OpenSSL库。如果是在Windows平台上,可以下载预编译的OpenSSL库。 2. 配置Qt项目 在Qt项目中,需要在.pro文件中添加以下配置: ``` QT += network LIBS += -L/path/to/openssl/lib -lssl -lcrypto INCLUDEPATH += /path/to/openssl/include ``` 其中,/path/to/opensslOpenSSL库的安装路径。通过上面的配置,可以将OpenSSL库链接到Qt项目中。 3. 使用OpenSSL库 在Qt使用OpenSSL库,可以参考以下示例代码: ```c++ #include <QSslSocket> #include <QSslCertificate> #include <QSslKey> int main() { // 初始化SSL库 QSslSocket::addDefaultCaCertificate(QSslCertificate::fromPath("ca.crt")); // 创建SSL套接字 QSslSocket socket; socket.setProtocol(QSsl::TlsV1_2); // 加载客户端证书和私钥 QSslCertificate clientCert("client.crt"); QSslKey clientKey("client.key", QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, "password"); socket.setLocalCertificate(clientCert); socket.setPrivateKey(clientKey); // 连接服务器 socket.connectToHostEncrypted("server.com", 443); if (!socket.waitForConnected()) { qDebug() << "Error: " << socket.errorString(); return -1; } // 发送请求数据 const char *request = "Hello, world!"; socket.write(request, strlen(request)); socket.waitForBytesWritten(); // 读取响应数据 QByteArray response; while (socket.waitForReadyRead()) { response += socket.readAll(); } qDebug() << "Received: " << response; // 关闭套接字 socket.disconnectFromHost(); socket.waitForDisconnected(); return 0; } ``` 在上面的示例中,首先使用addDefaultCaCertificate函数添加了CA证书。然后创建了QSslSocket对象,并设置TLS 1.2协议。接着加载了客户端证书和私钥,并连接到服务器。在连接成功后,通过write函数发送请求数据,并通过waitForBytesWritten函数等待数据发送完成。然后通过waitForReadyRead函数等待服务器响应数据,并通过readAll函数读取响应数据。最后关闭套接字。 注意,在实际使用中,需要根据实际情况修改证书和私钥的文件名、地址和端口等参数。同时,还需要处理连接错误和读写错误等异常情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值