Qt之Windows使用openssl(RSA加密)_qt openssl windows-程序员宅基地

技术标签: Qt  qt  

抄袭:大佬

openssl下载和qt例程:链接:https://pan.baidu.com/s/15avdzMeHgmB1qiWXB63Qow 
提取码:ulja

后续追加:添加了生成二维码,链接:https://pan.baidu.com/s/1lf-6-_LRtPehdq5P2h1h4w 
提取码:4sua

代码:

.pro文件添加了外部库

#-------------------------------------------------
#
# Project created by QtCreator 2022-04-14T10:20:16
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = win64OpensslTest
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
        main.cpp \

HEADERS += \

FORMS += \

INCLUDEPATH += ./openssl

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

win32: LIBS += -L$$PWD/./ -llibcrypto

INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.

win32: LIBS += -L$$PWD/./ -llibssl

INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/.

main.c文件

#include <QApplication>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <QDebug>
#define BEGIN_RSA_PUBLIC_KEY    "BEGIN RSA PUBLIC KEY"
#define BEGIN_PUBLIC_KEY        "BEGIN PUBLIC KEY"
#define KEY_LENGTH              1024                        // 密钥长度

/* 生成秘钥对 */
bool createRsaKey (QString& strPubKey, QString& strPriKey);
/* 私钥加密 */
QString rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey);
/* 公钥解密 */
QString rsa_pub_decrypt_base64 (const QString& strDecryptData, const QString& strPubKey);
/* 公钥加密 */
QString rsa_pub_encrypt_base64 (const QString& strClearData, const QString& strPubKey);
/* 私钥解密 */
QString rsa_pri_decrypt_base64 (const QString& strDecryptData, const QString& strPriKey);

bool createRsaKey (QString& strPubKey, QString& strPriKey)
{
     RSA *pRsa = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
     if ( !pRsa ){
         return false;
     }
     BIO *pPriBio = BIO_new(BIO_s_mem());
     PEM_write_bio_RSAPrivateKey(pPriBio, pRsa, NULL, NULL, 0, NULL, NULL);
     BIO *pPubBio = BIO_new(BIO_s_mem());
     PEM_write_bio_RSAPublicKey(pPubBio, pRsa);
     // 获取长度
     size_t nPriKeyLen = BIO_pending(pPriBio);
     size_t nPubKeyLen = BIO_pending(pPubBio);
     // 密钥对读取到字符串
     char* pPriKey = new char[nPriKeyLen];
     char* pPubKey = new char[nPubKeyLen];
     BIO_read(pPriBio, pPriKey, nPriKeyLen);
     BIO_read(pPubBio, pPubKey, nPubKeyLen);
     // 存储密钥对
     strPubKey = QByteArray(pPubKey, nPubKeyLen);
     strPriKey = QByteArray(pPriKey, nPriKeyLen);
     // 内存释放
     RSA_free(pRsa);
     BIO_free_all(pPriBio);
     BIO_free_all(pPubBio);
     delete pPriKey;
     delete pPubKey;
     return true;
}

QString rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey)
{
    QByteArray priKeyArry = strPriKey.toUtf8();
    uchar* pPriKey = (uchar*)priKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPriKey, strPriKey.length());
    if (pKeyBio == NULL){
        return "";
    }
    RSA* pRsa = RSA_new();
    pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
    if ( pRsa == NULL ){
         BIO_free_all(pKeyBio);
         return "";
    }
    int nLen = RSA_size(pRsa);
    char* pEncryptBuf = new char[nLen];
    memset(pEncryptBuf, 0, nLen);
    QByteArray clearDataArry = strClearData.toUtf8();
    int nClearDataLen = clearDataArry.length();
    uchar* pClearData = (uchar*)clearDataArry.data();
    int nSize = RSA_private_encrypt(nClearDataLen,
                                    pClearData,
                                    (uchar*)pEncryptBuf,
                                    pRsa,
                                    RSA_PKCS1_PADDING);
    QString strEncryptData = "";
    if ( nSize >= 0 ){
         QByteArray arry(pEncryptBuf, nSize);
         strEncryptData = arry.toBase64();
    }
    // 释放内存
    delete pEncryptBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strEncryptData;
}

QString rsa_pub_decrypt_base64(const QString& strDecryptData, const QString& strPubKey)
{
    QByteArray pubKeyArry = strPubKey.toUtf8();
    uchar* pPubKey = (uchar*)pubKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPubKey, strPubKey.length());
    if (pKeyBio == NULL){
        return "";
    }

    RSA* pRsa = RSA_new();
    if ( strPubKey.contains(BEGIN_RSA_PUBLIC_KEY) ){
        pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);
    }else{
        pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);
    }

    if ( pRsa == NULL ){
        BIO_free_all(pKeyBio);
        return "";
    }
    int nLen = RSA_size(pRsa);
    char* pClearBuf = new char[nLen];
    memset(pClearBuf, 0, nLen);
    //解密
    QByteArray decryptDataArry = strDecryptData.toUtf8();
    decryptDataArry = QByteArray::fromBase64(decryptDataArry);
    int nDecryptDataLen = decryptDataArry.length();
    uchar* pDecryptData = (uchar*)decryptDataArry.data();
    int nSize = RSA_public_decrypt(nDecryptDataLen,
                                   pDecryptData,
                                   (uchar*)pClearBuf,
                                   pRsa,
                                   RSA_PKCS1_PADDING);
    QString strClearData = "";
    if ( nSize >= 0 ){
        strClearData = QByteArray(pClearBuf, nSize);
    }

    // 释放内存
    delete pClearBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strClearData;
}

QString rsa_pub_encrypt_base64 (const QString& strClearData, const QString& strPubKey)
{
    QByteArray pubKeyArry = strPubKey.toUtf8();
    uchar* pPubKey = (uchar*)pubKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPubKey, pubKeyArry.length());
    if (pKeyBio == NULL){
        return "";
    }
    RSA* pRsa = RSA_new();
    if ( strPubKey.contains(BEGIN_RSA_PUBLIC_KEY) ){
        pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);
    }else{
        pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);
    }
    if ( pRsa == NULL ){
        BIO_free_all(pKeyBio);
        return "";
    }

    int nLen = RSA_size(pRsa);
    char* pEncryptBuf = new char[nLen];
    memset(pEncryptBuf, 0, nLen);

    QByteArray clearDataArry = strClearData.toUtf8();
    int nClearDataLen = clearDataArry.length();
    uchar* pClearData = (uchar*)clearDataArry.data();
    int nSize = RSA_public_encrypt(nClearDataLen,
                                   pClearData,
                                   (uchar*)pEncryptBuf,
                                   pRsa,
                                   RSA_PKCS1_PADDING);
    QString strEncryptData = "";
    if ( nSize >= 0 ){
        QByteArray arry(pEncryptBuf, nSize);
        strEncryptData = arry.toBase64();
    }
    // 释放内存
    delete pEncryptBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strEncryptData;
}

QString rsa_pri_decrypt_base64(const QString& strDecryptData, const QString& strPriKey)
{
    QByteArray priKeyArry = strPriKey.toUtf8();
    uchar* pPriKey = (uchar*)priKeyArry.data();
    BIO* pKeyBio = BIO_new_mem_buf(pPriKey, priKeyArry.length());
    if (pKeyBio == NULL){
        return "";
    }
    RSA* pRsa = RSA_new();
//    if ( strPriKey.contains(BEGIN_RSA_PUBLIC_KEY) ){
//        pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
//    }else{
//        pRsa = PEM_read_bio_RSA_Private(pKeyBio, &pRsa, NULL, NULL);
//    }
    pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
    if ( pRsa == NULL ){
        BIO_free_all(pKeyBio);
        return "";
    }
    int nLen = RSA_size(pRsa);
    char* pClearBuf = new char[nLen];
    memset(pClearBuf, 0, nLen);

    //解密
    QByteArray decryptDataArry = strDecryptData.toUtf8();
    decryptDataArry = QByteArray::fromBase64(decryptDataArry);
    int nDecryptDataLen = decryptDataArry.length();
    uchar* pDecryptData = (uchar*)decryptDataArry.data();
    int nSize = RSA_private_decrypt(nDecryptDataLen,
                                    pDecryptData,
                                    (uchar*)pClearBuf,
                                    pRsa,
                                    RSA_PKCS1_PADDING);
    QString strClearData = "";
    if ( nSize >= 0 ){
        strClearData = QByteArray(pClearBuf, nSize);
    }
    // 释放内存
    delete pClearBuf;
    BIO_free_all(pKeyBio);
    RSA_free(pRsa);
    return strClearData;
}

int main(int argc, char *argv[])
{
    /**< rsa private/public key 若从文件中拷贝出来,需要注意保存元先文件格式,即换行符需要带上,包括最后一行的换行符 */
    QString strPriKey = "";
    QString strPubKey = "";
    /**
     *  用代码生成的key与openssl命令生成的key区别:
     *  1、代码生成key,标题为 -----BEGIN RSA PUBLIC KEY-----,openssl命令生成key, 标题为 -----BEGIN PUBLIC KEY-----
     *  2、获取RSA函数不同,代码生成key,用PEM_read_bio_RSAPublicKey,openssl命令生成key,用PEM_read_bio_RSA_PUBKEY
    */
    createRsaKey(strPubKey, strPriKey);
    qDebug() << "strPubKey: " << strPubKey << endl;
    qDebug() << "strPriKey: " << strPriKey << endl;

    QString strClear = "helloworld";

    qDebug() << "private key encrypt, public key decrypt";
    QString strEncryptData = rsa_pri_encrypt_base64 (strClear, strPriKey);
    qDebug() << "strEncryptData: " << strEncryptData;
    QString strClearData = rsa_pub_decrypt_base64 (strEncryptData, strPubKey);
    qDebug() << "strClearData: " << strClearData;

    qDebug() << "public key encrypt, private key decrypt";
    strEncryptData = rsa_pub_encrypt_base64 (strClear, strPubKey);
    qDebug() << "strEncryptData: " << strEncryptData;
    strClearData = rsa_pri_decrypt_base64 (strEncryptData, strPriKey);
    qDebug() << "strClearData: " << strClearData;

}

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41399894/article/details/124166116

智能推荐

Google VR开发-Cardboard VR SDK反畸变实现_distortion_cardboard-程序员宅基地

文章浏览阅读2.9k次。上一篇文章分析了Cardboard SDK的生命周期设计。这里我们看下畸变部分的实现。Cardboard中将畸变这部分封装成了一个Distortion类和DistortionRenderer类。我们看下Distortion这个类: private static final float[] DEFAULT_COEFFICIENTS = { 250.0F, 50000.0_distortion_cardboard

解决Mysql Error:The user specified as a definer (‘mysql.infoschema’@’localhost’) does not exist_the user specified as a definer ('mysgl.infoschema-程序员宅基地

文章浏览阅读1.1w次,点赞3次,收藏4次。SET GLOBAL innodb_fast_shutdown = 1;2.mysql_upgrade -u root -p_the user specified as a definer ('mysgl.infoschema'@'localhost') does not ex

win10退出微软账号_用注册表编辑器退出微软账号-程序员宅基地

文章浏览阅读6.8k次,点赞13次,收藏33次。如何退出微软账号,改成本地账号登录?有人发现,在win10上登录微软账号后,微软账号就自动与本地账号绑定了,不可解除绑定。那除了重置电脑,还有什么方法呢?1、首先进入注册表:win+R 输入:regedit2、依次输入下列两个地址,并删除"邮箱账号这一项"HKEY_CURRENT_USER\Software\Microsoft\IdentityCRL\UserExtendedProperties\邮箱账号HKEY_USERS\.DEFAULT\Software\Microsoft\Ide_用注册表编辑器退出微软账号

Shell命令学习_sh命令-程序员宅基地

文章浏览阅读1k次。What is Shell?Shell 是一个应用程序,它连接了用户和 Linux 内核,让用户能够更加高效、安全、低成本地使用 Linux 内核,这就是 Shell 的本质。Shell 本身并不是内核的一部分,它只是站在内核的基础上编写的一个应用程序,它和 QQ、Firefox 等其它软件没有什么区别。然而 Shell 也有着它的特殊性,就是开机立马启动,并呈现在用户面前;用户通过 Shell 来使用 Linux,不启动 Shell 的话,用户就没办法使用 Linux。Shell 是如何连接用户和内_sh命令

USB学习(3):USB描述符和USB类设备_usb 接口描述符 class-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏14次。它描述了高速USB设备的信息,如果设备以另一速度运行,该描述符将发生更改,这在支持两种速度配置的设备中是必需的。同样,如果在设备以高速运行时请求此描述符,描述符读取将告诉主机有关全速配置的信息。在上一节的USB描述符部分,USB设备类的定义在:设备描述符的第四个字节和接口描述符的第六个字节。接口描述符描述了配置中的特定接口,此描述符中确定了接口的端点数量,声明了设备的USB类,供主机加载适合适驱动程序。设备描述符提供给主机一些信息,如设备符合的USB规范、设备支持的配置数量、支持的协议、制造商标识(_usb 接口描述符 class

java留言板源码_jsp留言板示例源码下载(入门级)-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏4次。【实例简介】留言板,主要用于初学者利用开发其他软件采用纯jsp页面 Mysql的方法实现功能项目编码是gb2312,要转换格式的请自己装换,界面简洁,功能简单,实现容易,非常适合初学者有助于加深初学者对jsp的理解和使用Mysql数据库String DBDRIVER= "com.mysql.jdbc.Driver";String DBURL="jdbc:mysql://localhost:3306..._jsp云日记源码

随便推点

VMware中如何实现Linux系统与宿主机文件共享_vmwarelinux与宿主机共享内存-程序员宅基地

文章浏览阅读820次。参考:http://hi.baidu.com/fly_2009hui/blog/item/a62b484f0f4ac63baec3ab73.html使用hgfs实现vmare文件传输一法使用vmware(vmware workstation 5)下shared folders功能实现vmware中host与ghost间文件传输,无需任何网络相关设置,不使用任何网络协议,host和gho_vmwarelinux与宿主机共享内存

go 源码篇(三)CSP GMP Channel_golang 开源csp-程序员宅基地

文章浏览阅读576次。1goroutine原理1.1基本概念并发:一个CPU上能同时执行多项任务,在很短时间内,CPU来回切换任务执行(在某段很短时间内执行程序a,然后又迅速得切换到程序b去执行),有时间上的重叠(宏观上是同时的,微观仍是顺序执 行),这样看起来多个任务像是同时执行,这就是并发。并行当系统有多个CPU时,每个CPU同一时刻都运行任务,互不抢占自己所在的CPU资源,同时进行, 称为并行。进程CPU在切换程序的时候,如果不保存上一个程序的状态(context–上下文),直接切换下一个程 序,就会丢失_golang 开源csp

高一计算机课期中考试总结反思,2017高一数学期中考试反思总结-程序员宅基地

文章浏览阅读76次。引导语:数学新课改的基本理念是:学有价值的数学,反映出学生实践能力和创新意识方面的不足,应引起我们的高度重视,学生的动手能力还有待提高。以下是百分网小编分享给大家的2017高一数学期中考试反思总结,欢迎阅读!过去的一学期里,我班在学校领导的统一组织下,在任课教师的大力支持和配合下,各项工作顺利开展,学习、生活等方面都取得较突出的成绩。现将本学期期中考试前的工作总结如下:一、 加强对学生的思想政治工...

如何使用Stripe和Syncano建立每日确认短信服务-程序员宅基地

文章浏览阅读276次。这篇文章是由赞助Syncano 。 感谢您支持谁使SitePoint可能的赞助商。 Syncano提供了实时应用的基于云的平台。 它存储数据,微服务代码,日程安排用于自动执行代码,用户帐户,网络挂接通过HTTP多以访问这些功能。 他们甚至已经得到的代码片段的开源社区,并支持多种运行环境,包括节点,巨蟒,围棋和Ruby。 从一个开发者角度,Syncano可以更容易获得通过提供大量的,否则你就需..._如何用stripe

MQ和ActiveMQ浅析_activemq和ibmmq的区别-程序员宅基地

文章浏览阅读844次。文章目录什么是JMS MQ消息中间件应用场景**异步通信**缓冲解耦冗余扩展性可恢复性顺序保证**过载保护****数据流处理**常用消息队列(ActiveMQ、RabbitMQ、RocketMQ、Kafka)比较JMS中的一些角色**Broker**providerConsumerp2ppub/subPTP 和 PUB/SUB 简单对QueueTopicConnectionFactoryConnectionDestinationSessionJMS的消息格式JMS消息由以下三部分组成的:TextMessag_activemq和ibmmq的区别

造梦师手记:SDXL更新最勤奋的梦幻模型_dreamshaper模型和sdxl模型的区别-程序员宅基地

文章浏览阅读238次。天道酬勤,这个模型也成为C站下载量最大的SDXL模型之一(当然,距离dreamshaperXL还有不小的差距)。但是,随着拥护者的增多,越来越多的建议得到反馈,就有望成为SDXL时代的顶尖少数几个大模型之一。可以预见的未来,至少在SDXL时代,由于SDXL本身的强大数据集,模型也会出现“马太效应”,会向极少数模型聚集。当然了,如果你能习惯comfyUI,也是非常不错的,这个UI虽然对很多新手界面不太友好,但对系统资源占用较少。短短不到一个月的时间,涌现出大量的模型和LoRA,丰富了我们的创作素材。_dreamshaper模型和sdxl模型的区别