给你的Qt软件加个授权

2024-04-12 11:20
文章标签 qt 软件 授权 加个

本文主要是介绍给你的Qt软件加个授权,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面

环境:

Win11 64位

VS2019 + Qt5.15.2

核心思路:

将授权相关信息加密保存到License.txt中,软件运行时获取并解密授权信息,判断是否在限制期限内即可。

加解密部分使用第三方openssl库进行,因此需要手动在项目中链接下openssl库,参考步骤如下。

链接openssl库

①官网下载openssl库安装包
官网链接:https://slproweb.com/products/Win32OpenSSL.html

下载自己当前操作系统位数对应的安装包即可,我当前系统为Win11 64位,因此下载以下安装包:
1

②双击安装。注意勾选添加到系统环境变量:
2
③打开安装目录如下:
3

④拷贝include文件夹到项目路径下:
4
⑤拷贝当前项目使用运行库对应的lib到项目路径下,这里使用MD Release版本中的动态库:
5
不会全部用到,可按需选择使用。

例如只用到以下三个库:
6
⑥在项目中链接这三个库,包含相应头文件即可使用:
7

示例

//AuthorizationManager.h
#pragma once
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>struct MyLicense
{int nAuthorizationStatus{ 1 };    //0: 未授权 1: 已授权std::string sFirstRunDate;    //首次运行日期int nAuthorizationDays{ -1 };        //授权天数std::string Serialize(){std::ostringstream os;os << nAuthorizationStatus << "\n" << sFirstRunDate << "\n" << nAuthorizationDays << "\n";return os.str();}void Deserialize(const std::string& str){std::istringstream is(str);is >> nAuthorizationStatus;is.ignore();std::getline(is, sFirstRunDate);sFirstRunDate = sFirstRunDate.substr(0, sFirstRunDate.length());is >> nAuthorizationDays;}
};class AuthorizationManager
{
public:static AuthorizationManager& Instance(){static AuthorizationManager instance;return instance;}AuthorizationManager(const AuthorizationManager&) = delete;AuthorizationManager& operator=(const AuthorizationManager&) = delete;std::string do_encrypt(const std::string& plaintext, const std::string& key, const std::string& iv);std::string do_decrypt(const std::string& ciphertext, const std::string& key, const std::string& iv);bool AuthorizationVerify();private:AuthorizationManager() = default;};
#include "AuthorizationManager.h"
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <vector>
#include <QDate>std::string AuthorizationManager::do_encrypt(const std::string& plaintext, const std::string& key, const std::string& iv)
{EVP_CIPHER_CTX* ctx;std::vector<unsigned char> ciphertext(plaintext.size() + EVP_MAX_BLOCK_LENGTH);int len;int ciphertext_len;if (!(ctx = EVP_CIPHER_CTX_new())){return "";}if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)key.c_str(), (const unsigned char*)iv.c_str())){return "";}if (1 != EVP_EncryptUpdate(ctx, ciphertext.data(), &len, (const unsigned char*)plaintext.c_str(), plaintext.size())){return "";}ciphertext_len = len;if (1 != EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len)){return "";}ciphertext_len += len;EVP_CIPHER_CTX_free(ctx);return std::string((char*)ciphertext.data(), ciphertext_len);
}std::string AuthorizationManager::do_decrypt(const std::string& ciphertext, const std::string& key, const std::string& iv)
{EVP_CIPHER_CTX* ctx;std::vector<unsigned char> plaintext(ciphertext.size());int len;int plaintext_len;if (!(ctx = EVP_CIPHER_CTX_new())){return "";}if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*)key.c_str(), (const unsigned char*)iv.c_str())){return "";}if (1 != EVP_DecryptUpdate(ctx, plaintext.data(), &len, (const unsigned char*)ciphertext.c_str(), ciphertext.size())){return "";}plaintext_len = len;if (1 != EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len)){return "";}plaintext_len += len;EVP_CIPHER_CTX_free(ctx);return std::string((char*)plaintext.data(), plaintext_len);
}bool AuthorizationManager::AuthorizationVerify()
{//密钥对,妥善保管std::string key = "98765432100123456789987654321001";std::string iv = "9876543210012345";//构造授权//MyLicense original;//original.nAuthorizationStatus = 1;//original.sFirstRunDate = "2024-04-08";//original.nAuthorizationDays = 90;//std::string serialized_str = original.Serialize();//std::string ciphertext = AuthorizationManager::Instance().do_encrypt(serialized_str, key, iv);//std::ofstream outfile("License.txt", std::ios::binary);//outfile << ciphertext;//outfile.close();//获取授权std::ifstream infile("License.txt", std::ios::binary);std::stringstream ss;ss << infile.rdbuf();std::string content = ss.str();std::string decryptedtext = AuthorizationManager::Instance().do_decrypt(content, key, iv);MyLicense restored;restored.Deserialize(decryptedtext);//授权校验bool bRet = false;if (restored.nAuthorizationStatus == 0){//首次运行授权MyLicense original;original.nAuthorizationStatus = 1;QDate curDate = QDate::currentDate();std::string sCurDate = curDate.toString("yyyy-MM-dd").toStdString();original.sFirstRunDate = sCurDate;original.nAuthorizationDays = restored.nAuthorizationDays;std::string serialized_str = original.Serialize();std::string ciphertext = AuthorizationManager::Instance().do_encrypt(serialized_str, key, iv);std::ofstream outfile("License.txt", std::ios::binary);outfile << ciphertext;outfile.close();bRet = true;}else{QDate curDate = QDate::currentDate();QDate firstRunDate = QDate::fromString(QString::fromStdString(restored.sFirstRunDate), "yyyy-MM-dd");QDate endDate = firstRunDate.addDays(restored.nAuthorizationDays);if (curDate < firstRunDate){bRet = false;}else if (curDate > endDate){bRet = false;}else{bRet = true;}}return bRet;
}
//main.cpp
#include "AuthorizationWidget.h"
#include <QtWidgets/QApplication>
#include "AuthorizationManager.h"int main(int argc, char* argv[])
{QApplication a(argc, argv);//授权检查if (!AuthorizationManager::Instance().AuthorizationVerify()){//未授权,退出软件return false;}AuthorizationWidget w;w.show();return a.exec();
}

这篇关于给你的Qt软件加个授权的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

Ubuntu 怎么启用 Universe 和 Multiverse 软件源?

《Ubuntu怎么启用Universe和Multiverse软件源?》在Ubuntu中,软件源是用于获取和安装软件的服务器,通过设置和管理软件源,您可以确保系统能够从可靠的来源获取最新的软件... Ubuntu 是一款广受认可且声誉良好的开源操作系统,允许用户通过其庞大的软件包来定制和增强计算体验。这些软件

python与QT联合的详细步骤记录

《python与QT联合的详细步骤记录》:本文主要介绍python与QT联合的详细步骤,文章还展示了如何在Python中调用QT的.ui文件来实现GUI界面,并介绍了多窗口的应用,文中通过代码介绍... 目录一、文章简介二、安装pyqt5三、GUI页面设计四、python的使用python文件创建pytho

QT实现TCP客户端自动连接

《QT实现TCP客户端自动连接》这篇文章主要为大家详细介绍了QT中一个TCP客户端自动连接的测试模型,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录版本 1:没有取消按钮 测试效果测试代码版本 2:有取消按钮测试效果测试代码版本 1:没有取消按钮 测试效果缺陷:无法手动停

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

Qt实现文件的压缩和解压缩操作

《Qt实现文件的压缩和解压缩操作》这篇文章主要为大家详细介绍了如何使用Qt库中的QZipReader和QZipWriter实现文件的压缩和解压缩功能,文中的示例代码简洁易懂,需要的可以参考一下... 目录一、实现方式二、具体步骤1、在.pro文件中添加模块gui-private2、通过QObject方式创建

Qt QWidget实现图片旋转动画

《QtQWidget实现图片旋转动画》这篇文章主要为大家详细介绍了如何使用了Qt和QWidget实现图片旋转动画效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 一、效果展示二、源码分享本例程通过QGraphicsView实现svg格式图片旋转。.hpjavascript

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

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

软件设计师备考——计算机系统

学习内容源自「软件设计师」 上午题 #1 计算机系统_哔哩哔哩_bilibili 目录 1.1.1 计算机系统硬件基本组成 1.1.2 中央处理单元 1.CPU 的功能 1)运算器 2)控制器 RISC && CISC 流水线控制 存储器  Cache 中断 输入输出IO控制方式 程序查询方式 中断驱动方式 直接存储器方式(DMA)  ​编辑 总线 ​编辑

【STM32】SPI通信-软件与硬件读写SPI

SPI通信-软件与硬件读写SPI 软件SPI一、SPI通信协议1、SPI通信2、硬件电路3、移位示意图4、SPI时序基本单元(1)开始通信和结束通信(2)模式0---用的最多(3)模式1(4)模式2(5)模式3 5、SPI时序(1)写使能(2)指定地址写(3)指定地址读 二、W25Q64模块介绍1、W25Q64简介2、硬件电路3、W25Q64框图4、Flash操作注意事项软件SPI读写W2