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中的接口函数。

0 0
原创粉丝点击