文章目录

  • 前言
  • 1、思路分析
  • 2、实现函数
  • 3、示例代码
  • 4、效果展示

前言

程序员为了防止自己的成果被白嫖,或者发布的软件在公司层面上要做一些防抄袭处理,这时就需要在软件层面上加锁、加密等操作。
1、单机终端软件
这类软件一般在未联网的情况下使用,所以不能通过网络去判定是否得到授权,一般采用绑定硬件信息来对软件进行加密,这样软件与设备绑定就无法进行随意使用。
2、远程授权监控
终端软件在启动后就会跟服务器通讯来检查当前设备是否已经得到授权,可实现远程锁定程序,设置程序的使用时间和使用次数。
以上两种方法都是最基础的软件加密方法,根据加密的算法的复杂度其破解的难度也不同,不过作为普通的一种加密方法已经够用了,市面上有比较成熟的加密加壳的软件,其安全程度要远高于软件加密的方法,下次抽时间介绍一下软件VMProtect的加、解密过程。

1、思路分析

单机软件想要每次启动前去验证是否有授权,需要从软件的配置中获取授权的验证信息,这里以软件的使用次数来举例,我们需要把软件的可使用次数写入配置文件ini或数据库中。每次在软件重新启动时,我们根据配置文件中信息来判断软件剩余的使用次数。

这里设定软件的剩余使用次数为2次,不过这里有一个很明显的缺点,就是明文写到配置文件里,就可以自己修改,然后就失去了加密的属性,这里就需要对这个信息进行加密后再写入。这里使用Qt自带的base64对字符串进行加密。

2、实现函数

//加密
QString Widget::Encode(QString row)
{QByteArray byteArray = row.toUtf8();byteArray = byteArray.toBase64();return  byteArray;
}
//解密
QString Widget::Decode(QString passwd)
{QByteArray byteArray = passwd.toUtf8();byteArray = QByteArray::fromBase64(byteArray);return byteArray;
}
//从配置文件获取信息
QString Widget::getInfoFromIni(QString str)
{QString info;QFile file(str);if(!file.exists()) { //如果文件不存在QString times_str = "RemainTime:"+time;WriteInfo2Ini(str, times_str);}file.open(QFile::ReadWrite | QFile::Text);info = file.readAll(); //读取信息file.close();return info;
}
//将信息写入到配置文件
void Widget::WriteInfo2Ini(QString str, QString info_text)
{QFile file(str);file.open(QFile::ReadWrite | QFile::Text | QFile::Truncate);file.write(Encode(info_text).toUtf8()); //写入信息file.close();
}

这种方法有一种弊端,就是如果重新覆盖配置文件可以跳出限制,比如这里如果事前拷贝一份ini文件,当软件次数为0后,重新拷贝原始ini文件后又获得初始的软件使用次数。
如果考虑不使用ini文件来记录授权信息,而是使用注册表来记录授权信息,这样软件使用者就不容易去发现授权信息的位置

void Widget::WriteInfo2Registry(QString str)
{//写入注册表QSettings settings("HKEY_CURRENT_USER\\Software\\Code_Encryption\\Settings",QSettings::NativeFormat);settings.setValue("remain_times",Encode(str).toUtf8());
}QString Widget::getInfoFromRegistry()
{QString info;//通过写入注册表来判断QSettings settings("HKEY_CURRENT_USER\\Software\\Code_Encryption\\Settings",QSettings::NativeFormat);info = settings.value("remain_times").toString();return info;
}

3、示例代码

widget.cpp

#pragma execution_character_set("utf-8")
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);QString str = getCpuId();qDebug()<<"cpu id is"<<str;
//    QString times_str = "RemainTime:"+time;
//    WriteInfo2Registry(times_str);Judge_Authorize_times(1);
}Widget::~Widget()
{delete ui;
}QString Widget::getWMIC(const QString &cmd)
{//获取cpu名称:wmic cpu get Name//获取cpu核心数:wmic cpu get NumberOfCores//获取cpu线程数:wmic cpu get NumberOfLogicalProcessors//查询cpu序列号:wmic cpu get processorid//查询主板序列号:wmic baseboard get serialnumber//查询BIOS序列号:wmic bios get serialnumber//查看硬盘:wmic diskdrive get serialnumberQProcess p;p.start(cmd);p.waitForFinished();QString result = QString::fromLocal8Bit(p.readAllStandardOutput());QStringList list = cmd.split(" ");result = result.remove(list.last(), Qt::CaseInsensitive);result = result.replace("\r", "");result = result.replace("\n", "");result = result.simplified();return result;
}QString Widget::getCpuId() //获取CPU序列号
{return getWMIC("wmic cpu get processorid");
}QString Widget::getDiskNum() //获取硬盘序列号
{return getWMIC("wmic diskdrive where index=0 get serialnumber");
}QString Widget::Encode(QString row)
{QByteArray byteArray = row.toUtf8();byteArray = byteArray.toBase64();return  byteArray;
}
QString Widget::Decode(QString passwd)
{QByteArray byteArray = passwd.toUtf8();byteArray = QByteArray::fromBase64(byteArray);return byteArray;
}QString Widget::getInfoFromIni(QString str)
{QString info;QFile file(str);if(!file.exists()) { //如果文件不存在QString times_str = "RemainTime:"+time;WriteInfo2Ini(str, times_str);}file.open(QFile::ReadWrite | QFile::Text);info = file.readAll(); //读取信息file.close();return info;
}void Widget::WriteInfo2Ini(QString str, QString info_text)
{QFile file(str);file.open(QFile::ReadWrite | QFile::Text | QFile::Truncate);file.write(Encode(info_text).toUtf8()); //写入信息file.close();
}void Widget::WriteInfo2Registry(QString str)
{//写入注册表QSettings settings("HKEY_CURRENT_USER\\Software\\Code_Encryption\\Settings",QSettings::NativeFormat);settings.setValue("remain_times",Encode(str).toUtf8());
}QString Widget::getInfoFromRegistry()
{QString info;//通过写入注册表来判断QSettings settings("HKEY_CURRENT_USER\\Software\\Code_Encryption\\Settings",QSettings::NativeFormat);info = settings.value("remain_times").toString();return info;
}void Widget::Judge_Authorize_times(int type)
{QString times_info;if(type == 0){//通过ini配置文件进行判断times_info = getInfoFromIni("System.ini");}else{//通过写入注册表来判断times_info = getInfoFromRegistry();}if(times_info.isEmpty()){QMessageBox::about(this,"提示","授权信息为空,请检查!");exit(0);}else{QString info = Decode(times_info); //解码if(info.contains(':')) {  //信息正确QStringList list = info.split(':');if(list.length()>=1) {if(list[1].toInt() <= 0) {    //程序剩余使用次数不足QMessageBox::about(this,"提示","请注册后再使用!");exit(0); //程序退出}else {  //程序还有剩余使用次数QString time_remain = QString::number(list[1].toInt()-1); //程序剩余使用次数减1QString str = "RemainTime:"+time_remain;if(type == 0) WriteInfo2Ini("System.ini", str);else {//写入注册表WriteInfo2Registry(str);}QMessageBox::about(this,"提示","程序剩余使用次数:"+time_remain+"次");}}}}}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QFile>
#include <QMessageBox>
#include <QProcess>
#include <QDebug>
#include <QSettings>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;QString getWMIC(const QString &cmd);QString getCpuId();QString getDiskNum();//加密QString Encode(QString row);//解密QString Decode(QString passwd);//判断授权信息  0:使用ini方法判断;1:使用注册表方法判断void Judge_Authorize_times(int type);//从ini获取授权信息QString getInfoFromIni(QString str);//写入授权信息到inivoid WriteInfo2Ini(QString str, QString info_text);//从注册表获取授权信息QString getInfoFromRegistry();//写入授权信息到注册表void WriteInfo2Registry(QString str);//授权程序使用次数为2次QString time = "2";};#endif // WIDGET_H

4、效果展示


源码放到gitee仓库:Code_Encryption源码

[Qt学习笔记]Qt程序加密,实现软件运行次数和硬件信息绑定相关推荐

  1. Qt学习笔记(二)【软件样式及界面外观设置】

    Qt是一个跨平台的类库,相同的界面组件在不同的操作系统上显示效果是不一样的. 在windows7系统中,默认样式有:windows,fusion两个:通过安装Qt Creator编译器后,系统中会自动 ...

  2. Qt学习笔记-Qt5程序开机自启动(windows)

    原博文地址为:https://blog.csdn.net/x356982611/article/details/53183144 简介 window下开机启动最简单的实现方式就是在注册表中添加启动项目 ...

  3. Qt学习笔记-Qt程序切换皮肤

    运行截图如下: 首先我们从网上随便搞一个别人写好的QSS(这个东西其实自己写更有意思) 本人自己写的还没完善,为了做这个笔记,先用网上的, QSS代码如下: /* === Shared === */ ...

  4. Qt学习笔记-Qt中OpenGL的使用

    现在窗口中心即为坐标原点,X轴从左到右,Y轴从下到上,Z轴从里到外. 程序运行截图如下: 源码如下: myglwidget.h #ifndef MYGLWIDGET_H #define MYGLWID ...

  5. Qt学习笔记-Qt Graphic View Framework

    逻辑: 1.创建一场景 -> QGraphicsScene 2.创建一个视图 -> QGraphicsView 3.往场景添加Item -> QGraphicsSimpleTextI ...

  6. Qt学习笔记,Qt程序架构设计要旨

    Qt学习笔记,Qt程序架构设计要旨 时间过得很快,转眼学习Qt已经有一个多月了,对Qt的学习也在不断的深入中.自己手下的code也很多了,不过不得不说,还有很多的部分没有接触过,比如网络编程,2D,3 ...

  7. QT学习笔记(三):Qt软件打包发布(QT5.8 _msvc2013_64+Win10_64)

    QT学习笔记(三):Qt软件打包发布(QT5.8 _msvc2013_64+Win10_64) 1.编译方式介绍: 2.动态编译方式打包发布QT程序: 方法一:手动复制 方法二:使用工具 问题& ...

  8. Qt学习笔记之数据库

    一.数据库简介 1.1.数据和数据库(DB) 用计算机进行数据处理,首先就要把信息以数据形式存储到计算机中,故数据是可以被计算机接受和处理的符号.根据所表示的信息特征不同,数据有不同的类别,如数字.文 ...

  9. Qt学习笔记之国际化

    国际化的英文表述为Internationalization,通常简写为I18N(首尾字母加中间的字符数),一个应用程序的国际化就是使该应用程序可以让其他国家的用户使用的过程. 1. 相关的Qt类和AP ...

最新文章

  1. SpringSecurity实战:基于mysql自定义SpringSecurity权限认证规则
  2. python怎样定义一个数组_Python创建数组
  3. 用gnuplot画出c产生数据的波形图
  4. 吴恩达 coursera ML 第十四课总结+作业答案
  5. windows ce6.0系统 支持双网卡吗_MacBook双系统不求人,自己来
  6. MySQL性能调优与架构设计-架构篇
  7. securityPolicy与安全策略等级配置
  8. selenium爬取京东的手机分类页面下的商品信息
  9. 【论文阅读】利用深度自编码器神经网络预测药物相似度
  10. Codevs 5208 求乘方取模
  11. Kalman滤波在温度测量中的应用(含MATLAB仿真)
  12. 程序员如何搭建自己的知识体系?
  13. 关于ios13升级到ios14企业APP出现无法安装解决方案
  14. 高清青龙壁纸 桌面壁纸
  15. Oracle体系结构之内存结构(SGA、PGA)
  16. JavaScript实现注册功能
  17. 查看Windows凭据和普通凭据的密码(查看Windows中存储的密码)——mimikatz
  18. 小白兔和小灰兔【爱情故事系列暖暖的很贴心】
  19. POJ-29932996
  20. QQ宠物智能辅助开发

热门文章

  1. h2database源码解析-如何插入一条行记录
  2. 迭代函数系统(IFS)
  3. 应用数值分析(冯象初)2020年8月西安电子科技大学出版-课后参考答案-第1章
  4. dell服务器开机账号破解,dell解密595B 2A7B开机密码算号器-BIOS维修网站www.biosrepair.com...
  5. 红旗linux进入控制台,解除红旗LINUX4.1的一些限制/自定义控制面板(转)
  6. 动手开发自己的mvc-3----容器该帮我们做什么?(非常的重点)
  7. 第十三课 讲解DELPHI的网络验证
  8. “好奇号”使用X波段通讯(卷积码)
  9. 电脑关机或重启C盘数据被清空还原问题
  10. 2019 AMC8中文