License系统设计(二)
来源:互联网 发布:python 字典遍历 编辑:程序博客网 时间:2024/05/17 06:21
本文主要讲解License Generator的实现,总体设计请参考前一篇文章。
一、导出导入库
License Generator是采用QT实现的,它需要导入前面的加解密DLL。导入库的设计如下:
#ifndef AES_DLL_H#define AES_DLL_H#ifdef AES_IMPORT#define AES_API extern "C" __declspec(dllexport)#else#define AES_API extern "C" __declspec(dllimport)#endif#include <string>using std::string;class IEncryptor{public:virtual void SetKey(unsigned char * key, unsigned char * iv, int length) = 0;// encrypt the plainText and generate a file, the plainText should be a string with '\0' endvirtual bool EncryptString2File(const char * plainText, const char * outFilename) = 0;// decyrpt the file and output the recover, you may calculate the size of the file and allocate the space for recovervirtual bool DecryptFile2String(const char * decFilename, char * recoverText) = 0;};AES_API IEncryptor* CreateEncryptor();AES_API void ReleaseEncryptor(IEncryptor* pEncryptor);typedef IEncryptor* (*pfnCreateEncryptor)();typedef void (*pfnReleaseEncryptor)(IEncryptor*);#endif // AES_DLL_H
它主要包括两个导出函数,和一个接口类。这两个导出函数主要复杂管理类对象,主要功能还是在这个接口类中。
这个接口类提供了三个接口:
1)设置加解密的密匙;
2)加密字符串并生成加密文件;
3)将加密文件解密,并输出字符串;
二、初始化
我将加密库的载入和密匙的设置放到MainWindow的构造函数中,如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_library("EncryptorDll.dll"), m_pEncryptor(nullptr){ ui->setupUi(this); QString currentDate = (QDate::currentDate()).toString("yyyy/MM/dd"); QString Deadline = (QDate::currentDate().addMonths(1)).toString("yyyy/MM/dd"); ui->lineEdit_6->setText(currentDate); ui->lineEdit_7->setText(Deadline); ui->lineEdit_8->setText(currentDate); unsigned char key[]= {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, 0x0B,0x0C,0x0D,0x0E,0x0F,0x10}; //AES::DEFAULT_KEYLENGTH unsigned char iv[]= {0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06, 0x05,0x04,0x03,0x02,0x01,0x10}; int keysize = 16; m_library.load(); if (m_library.isLoaded()) { pfnCreateEncryptor pCreate = (pfnCreateEncryptor)m_library.resolve("CreateEncryptor"); if (pCreate) { m_pEncryptor = pCreate(); m_pEncryptor->SetKey(key,iv,keysize); } }}
加解密DLL库载入成功后,会解析出导入函数“CreateEncryptor”,然后调用该函数,创建真正的加解密类对象,并设置密匙。
三、预览
下面是“Preview”控件的响应函数
void MainWindow::on_btnPreview_clicked(){ QString strPlain{"f0f0,"}; int count = 8; QLabel* arrLabel[8] = {ui->label_1,ui->label_2,ui->label_3,ui->label_4, ui->label_5,ui->label_6,ui->label_7,ui->label_8}; QLineEdit* arrLine[8] = {ui->lineEdit_1,ui->lineEdit_2,ui->lineEdit_3,ui->lineEdit_4, ui->lineEdit_5,ui->lineEdit_6,ui->lineEdit_7,ui->lineEdit_8}; for (int i = 0; i < count; ++i) { strPlain += arrLabel[i]->text(); strPlain += arrLine[i]->text(); strPlain += ','; } strPlain += "0f0f"; ui->plaintext->setPlainText(strPlain);}
四、加密和解密
下面是加密和解密按键的响应函数
void MainWindow::on_btnEncrypt_clicked(){ string plainText = ui->plaintext->toPlainText().toStdString(); string fileName = ui->lineEdit_3->text().toStdString() + ".license"; if (m_pEncryptor->EncryptString2File(plainText.c_str(), fileName.c_str())) { ui->ciphertext->setPlainText("Encrypt succeed!"); } else { ui->ciphertext->setPlainText("Encrypt failed!"); }}void MainWindow::on_btnDecrypt_clicked(){ string fileName = ui->lineEdit_3->text().toStdString() + ".license"; QFileInfo fileInfo(fileName.c_str()); char * recover = new char[fileInfo.size()]; if (m_pEncryptor->DecryptFile2String(fileName.c_str(), recover)) { ui->recovertext->setPlainText(QString(recover)); } else { ui->recovertext->setPlainText(QString("Recover failed!")); }}
五、补充说明
原始的Cryptoo++库,推荐用静态库的方式嵌入程序,但是,我之前一直没在Qt中尝试成功过“静态库”的加载,甚至“动态链接库的非Load加载方式”也多次尝试失败。因此,逼得我设计除了“Interface Class”的方式,并在Qt中用QLibrary加载VS生成的DLL。
今天,我偷闲又试验了一把“Qt非Load方式加载DLL”,竟然成功了,特此补充。我还是用这个License工程为实验对象。“Qt非Load方式加载DLL”其实也不复杂,可以分为三步,事实上,静态库也可以按这个方法加载。
1,使用QCreator,打开宿主工程,在“项目”窗口,右键“项目目录树的根节点”,选择“添加库”。
2,在弹出来的对话框中,选择“库类型”为“外部库”,然后选择待添加的库的路径。
注:仔细观察上图,它是可以选择静态库的。
3,点击“下一步”,Qcreator将在*.pro文件添加以下代码
事实上,Qt非Load方式加载DLL仅需要添加这些代码。
注:做完以上工作,即可以加载DLL了。下面,我再以LicenseSystem为例,修改代码如下:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), //m_library("EncryptorDll.dll"), m_pEncryptor(nullptr){ ui->setupUi(this); QString currentDate = (QDate::currentDate()).toString("yyyy/MM/dd"); QString Deadline = (QDate::currentDate().addMonths(1)).toString("yyyy/MM/dd"); ui->lineEdit_6->setText(currentDate); ui->lineEdit_7->setText(Deadline); ui->lineEdit_8->setText(currentDate); unsigned char key[]= {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A, 0x0B,0x0C,0x0D,0x0E,0x0F,0x10}; //AES::DEFAULT_KEYLENGTH unsigned char iv[]= {0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06, 0x05,0x04,0x03,0x02,0x01,0x10}; int keysize = 16;// m_library.load();// if (m_library.isLoaded())// {// pfnCreateEncryptor pCreate = (pfnCreateEncryptor)m_library.resolve("CreateEncryptor");// if (pCreate)// {// m_pEncryptor = pCreate();// m_pEncryptor->SetKey(key,iv,keysize);// }// } m_pEncryptor = CreateEncryptor(); m_pEncryptor->SetKey(key,iv,keysize);}MainWindow::~MainWindow(){ delete ui;// if (m_library.isLoaded())// {// pfnReleaseEncryptor pRelease = (pfnReleaseEncryptor)m_library.resolve("ReleaseEncryptor");// if (pRelease)// {// pRelease(m_pEncryptor);// }// m_library.unload();// } ReleaseEncryptor(m_pEncryptor);}
注:以上注释了QLibrary和Load,直接调用DLL中的接口函数。
- License系统设计(二)
- License系统设计(一)
- PyQt实现一个简单的License系统(二)
- 日志系统设计(二)
- 系统设计经验谈(二)
- 业务系统设计之二:系统主控设计(上)
- 日志系统设计(一)&(二)
- 系统设计之 网络模型(二)
- 系统设计之 状态机(二)
- 铁道部新客票系统设计(二)
- 铁道部新客票系统设计(二)
- 系统设计之 网络模型(二)
- 铁道部新客票系统设计(二)
- 铁道部新客票系统设计(二)
- 【系统性能优化】(二)数据库设计
- 智能家居网络系统设计(二)
- 电子相册系统(二)业务层设计
- SparkML(二) 设计机器学习系统
- 侧滑菜单(三):DrawLayout
- 高并发网络Epoll机制详解
- python中装饰器的使用和类装饰器在类中方法的使用
- java 定时跑批数字意义简单介绍
- 使用IDEA部署tomcat产生异常:NameNotFoundException
- License系统设计(二)
- Bootstrap 模态框在点击页面空白处关闭
- CentOS 6.0 系统 LAMP(Apache+MySQL+PHP)安装步骤
- 小技巧-windows系统下cmd及Bash的粘贴复制快捷操作
- HDFS的运行原理
- C# MDI编程中子窗体调用子窗体的问题
- golang 使用gops进行程序监控
- H5移动前端开发常用高能css3汇总
- sql数据库基本语句