|
|
|
|
#include "Auth.h"
|
|
|
|
|
#include <QDateTime>
|
|
|
|
|
#include "Utils.h"
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
|
|
|
|
Auth *Auth::m_pInstance = nullptr;
|
|
|
|
|
std::mutex Auth::m_mutex;
|
|
|
|
|
|
|
|
|
|
Auth::Auth()
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
m_isEncrypt = true;
|
|
|
|
|
m_bTimesFlag = false;
|
|
|
|
|
m_companyName = "";
|
|
|
|
|
m_date = "19700101";
|
|
|
|
|
m_times = 0;
|
|
|
|
|
m_cfgFileName = "tmskey.cfg";
|
|
|
|
|
m_desKey = "tmskey2021_zwzxfyxcytq!";
|
|
|
|
|
|
|
|
|
|
m_hexDesKey = Utils::strToHexStr(m_desKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Auth::~Auth()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Auth::getOriginString()
|
|
|
|
|
{
|
|
|
|
|
std::string str = "";
|
|
|
|
|
|
|
|
|
|
// 公司名
|
|
|
|
|
str.append(m_companyName);
|
|
|
|
|
|
|
|
|
|
// 产品类型,UCHAR转为HEX格式
|
|
|
|
|
str.append(",");
|
|
|
|
|
//str.append(Utils::strToHexStr(Utils::ucharToStr(m_productType)));
|
|
|
|
|
str.append(Utils::ucharToHexStr(m_productType));
|
|
|
|
|
|
|
|
|
|
// 使用期限
|
|
|
|
|
str.append(",");
|
|
|
|
|
str.append(m_publishDate); // 发布日期
|
|
|
|
|
str.append(",");
|
|
|
|
|
str.append(m_date); // 使用期限
|
|
|
|
|
|
|
|
|
|
// 使用次数
|
|
|
|
|
str.append(",");
|
|
|
|
|
str.append(m_bTimesFlag ? "1" : "0");
|
|
|
|
|
str.append(",");
|
|
|
|
|
str.append(std::to_string(m_times));
|
|
|
|
|
|
|
|
|
|
// 高级设置密码 - 后续考虑密码额外加密
|
|
|
|
|
str.append(",");
|
|
|
|
|
str.append(Utils::strToHexStr(m_advancePwd));
|
|
|
|
|
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", tr("Origin String : %1").arg(str), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string Auth::toMessage()
|
|
|
|
|
{
|
|
|
|
|
std::string str = "";
|
|
|
|
|
|
|
|
|
|
// 公司名
|
|
|
|
|
str.append("公司名 : ");
|
|
|
|
|
str.append(m_companyName);
|
|
|
|
|
str.append("\n");
|
|
|
|
|
|
|
|
|
|
// 产品类型
|
|
|
|
|
str.append("产品类型 : \n");
|
|
|
|
|
str.append("\t电动扳手").append((((m_productType >> 0) & 0x01) == 1) ? "(true)" : "(false)").append("\n");
|
|
|
|
|
str.append("\t充电扳手").append((((m_productType >> 1) & 0x01) == 1) ? "(true)" : "(false)").append("\n");
|
|
|
|
|
str.append("\t液压扳手").append((((m_productType >> 2) & 0x01) == 1) ? "(true)" : "(false)").append("\n");
|
|
|
|
|
str.append("\t气动扳手").append((((m_productType >> 3) & 0x01) == 1) ? "(true)" : "(false)").append("\n");
|
|
|
|
|
|
|
|
|
|
// 使用期限
|
|
|
|
|
str.append("发布日期 : ");
|
|
|
|
|
str.append(m_publishDate);
|
|
|
|
|
str.append("\n");
|
|
|
|
|
|
|
|
|
|
str.append("使用期限 : ");
|
|
|
|
|
str.append(m_date);
|
|
|
|
|
str.append("\n");
|
|
|
|
|
|
|
|
|
|
// 使用次数
|
|
|
|
|
str.append("使用次数标记 : ");
|
|
|
|
|
str.append(m_bTimesFlag ? "是" : "否");
|
|
|
|
|
str.append("\n");
|
|
|
|
|
str.append("使用次数 : ");
|
|
|
|
|
str.append(std::to_string(m_times));
|
|
|
|
|
str.append("\n");
|
|
|
|
|
|
|
|
|
|
// 高级设置密码
|
|
|
|
|
str.append("高级设置密码 : ");
|
|
|
|
|
str.append(m_advancePwd);
|
|
|
|
|
str.append("\n");
|
|
|
|
|
|
|
|
|
|
qDebug() << QObject::tr("Origin String : %1").arg(QString::fromStdString(str));
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::writeFile()
|
|
|
|
|
{
|
|
|
|
|
// 加密标记字节:
|
|
|
|
|
// 位0 | 位1 | 位2 | 位3 | 位4 | 位5 | 位6 | 位7
|
|
|
|
|
// 保留 | 加密标记 | 保留 | 1 | 保留 | 1 | 0 | 保留
|
|
|
|
|
// 取当前时间的秒,与上 1010 1001,即0xA9,去除非保留字节,然后加上0001 0100
|
|
|
|
|
// 获取当前时间的毫秒值与255的余数
|
|
|
|
|
unsigned char mSecond = QDateTime::currentDateTime().time().msec() % 255;
|
|
|
|
|
// 计算加密标记
|
|
|
|
|
// unsigned char a = mSecond & 0xA9;
|
|
|
|
|
// unsigned char b = m_isEncrypt ? 0x40 : 0x00;
|
|
|
|
|
// unsigned char c = a + b;
|
|
|
|
|
// unsigned char d = c + 0x14;
|
|
|
|
|
m_encryptFlag = (mSecond & 0xA9) // 去除指定位 1[0]1[0] 1[0][0]1,方括号内标记
|
|
|
|
|
+ (m_isEncrypt ? 0x40 : 0x00) // 加入加密标记 0[1]00 0000,方括号内标记,目前仅支持加密
|
|
|
|
|
+ (0x14); // 加入其他标记 000[1] 0[1][0]0,方括号内的标记
|
|
|
|
|
// 加密标记转hex
|
|
|
|
|
std::string hexEncryptFlag = Utils::charToHexStr(m_encryptFlag); //Utils::strToHexStr(Utils::charToStr(m_encryptFlag));
|
|
|
|
|
qDebug() << QObject::tr("加密标记: %1 , %2 ").arg(QString::fromStdString(hexEncryptFlag)).arg(m_encryptFlag);
|
|
|
|
|
|
|
|
|
|
// 参数加密 - des
|
|
|
|
|
// 获取参数字符串
|
|
|
|
|
std::string originStr = getOriginString();
|
|
|
|
|
qDebug() << QObject::tr("Origin String : %1").arg(QString::fromStdString(originStr));
|
|
|
|
|
|
|
|
|
|
// des加密
|
|
|
|
|
char strOut[2048];
|
|
|
|
|
bool bRet = m_des.Encrypt((char *)originStr.c_str(), (unsigned int)originStr.length(), m_hexDesKey.c_str(), (unsigned char)m_hexDesKey.length(), strOut);
|
|
|
|
|
if(!bRet)
|
|
|
|
|
{
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", tr("加密失败!"), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 加密结果转hex
|
|
|
|
|
std::string hexOut = Utils::strToHexStr(strOut);
|
|
|
|
|
qDebug() << QObject::tr("hex Origin String : %1").arg(QString::fromStdString(hexOut));
|
|
|
|
|
// 生成文件内容:加密标记+加密结果
|
|
|
|
|
std::string fileContent = "";
|
|
|
|
|
fileContent.append(hexEncryptFlag);
|
|
|
|
|
fileContent.append(hexOut);
|
|
|
|
|
// 写入文件
|
|
|
|
|
Utils::writeFile(m_cfgFileName, fileContent);
|
|
|
|
|
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", tr("write file : %1").arg(QString::fromStdString(fileContent)), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
qDebug() << QObject::tr("writeFile : %1").arg(QString::fromStdString(fileContent));
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::readFile()
|
|
|
|
|
{
|
|
|
|
|
// 读取文件
|
|
|
|
|
std::ifstream f(m_cfgFileName);
|
|
|
|
|
if(!f.good())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string fileContent = Utils::readFile(m_cfgFileName);
|
|
|
|
|
|
|
|
|
|
// 获取前两个hex字符,为加密标记的hex格式
|
|
|
|
|
std::string hexEncryptFlag = fileContent.substr(0, 2);
|
|
|
|
|
// 加密标记hex格式转字符
|
|
|
|
|
m_encryptFlag = Utils::strToChar(Utils::hexStrToStr(hexEncryptFlag));
|
|
|
|
|
qDebug() << QObject::tr("加密标记: %1 , %2 ").arg(QString::fromStdString(hexEncryptFlag)).arg(m_encryptFlag);
|
|
|
|
|
if(!checkEncryptFlag())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取文件剩余内容:参数加密后的hex格式
|
|
|
|
|
std::string hexOut = fileContent.substr(2);
|
|
|
|
|
qDebug() << QObject::tr("hex Origin String : %1").arg(QString::fromStdString(hexOut));
|
|
|
|
|
// hex格式的加密参数转字符串
|
|
|
|
|
std::string strOut = Utils::hexStrToStr(hexOut);
|
|
|
|
|
|
|
|
|
|
// des解密
|
|
|
|
|
char strOrigin[2048] = {0};
|
|
|
|
|
bool bRet = m_des.Decrypt((char *)strOut.c_str(), (unsigned int)strOut.length(), m_hexDesKey.c_str(), (unsigned char)m_hexDesKey.length(), strOrigin);
|
|
|
|
|
if(!bRet)
|
|
|
|
|
{
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", tr("解密失败"), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
qDebug() << QObject::tr("Origin String : %1").arg(strOrigin);
|
|
|
|
|
|
|
|
|
|
QStringList strList =QString(strOrigin).split(",");
|
|
|
|
|
if(strList.size() < 7)
|
|
|
|
|
{
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", tr("秘钥文件损坏!"), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int idx = 0;
|
|
|
|
|
setComanyName(strList[idx].toStdString());
|
|
|
|
|
idx++;
|
|
|
|
|
setProductType(Utils::hexStrToUchar(strList[idx].toStdString()));
|
|
|
|
|
idx++;
|
|
|
|
|
setPublishDate(strList[idx].toStdString());
|
|
|
|
|
idx++;
|
|
|
|
|
setDate(strList[idx].toStdString());
|
|
|
|
|
idx++;
|
|
|
|
|
setTimesFlag(((!strList[idx].isEmpty()) && (strList[idx].toInt() != 0)) ? true : false);
|
|
|
|
|
idx++;
|
|
|
|
|
setTimes(strList[idx].isEmpty() ? 0 : strList[idx].toInt());
|
|
|
|
|
idx++;
|
|
|
|
|
setAdvancePwd(Utils::hexStrToStr(strList[idx].toStdString()));
|
|
|
|
|
//QMessageBox::warning(this, "Warning!", strMsg, QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
|
|
|
|
|
qDebug() << QString::fromStdString(toMessage());
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::checkEncryptFlag()
|
|
|
|
|
{
|
|
|
|
|
// 0x0[1]0[1] 0[1][0]0,方括号内为需要检查的位
|
|
|
|
|
unsigned char b1 = m_encryptFlag >> 6 & 0x01;
|
|
|
|
|
if(b1 == 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
unsigned char b3 = m_encryptFlag >> 4 & 0x01;
|
|
|
|
|
if(b3 == 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
unsigned char b5 = m_encryptFlag >> 2 & 0x01;
|
|
|
|
|
if(b5 == 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
unsigned char b6 = m_encryptFlag >> 1 & 0x01;
|
|
|
|
|
if(b6 == 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::checkProductType()
|
|
|
|
|
{
|
|
|
|
|
// m_productType[1,2,4,8]取值范围:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
|
|
|
|
|
if(m_productType < 1 || m_productType > 15)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::checkDate()
|
|
|
|
|
{
|
|
|
|
|
// 如果设置日期小于发布日期
|
|
|
|
|
if(m_publishDate.compare(m_date) > 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string currDate = QDate::currentDate().toString("yyyyMMdd").toStdString();
|
|
|
|
|
// 发布日期大于当前日期
|
|
|
|
|
if(m_publishDate.compare(currDate) > 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// 使用期限小于当前日期
|
|
|
|
|
if(m_date.compare(currDate) < 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::checkTimes()
|
|
|
|
|
{
|
|
|
|
|
if(m_bTimesFlag)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 密码必须有大小写数字和特殊字符,长度必须大于等于8
|
|
|
|
|
bool Auth::checkAdvancePwd()
|
|
|
|
|
{
|
|
|
|
|
if(m_advancePwd.empty())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(m_advancePwd.length() < 8)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
std::string upperCharStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
|
std::string lowerCharStr = "abcdefghijklmnopqrstuvwxyz";
|
|
|
|
|
std::string digitStr = "0123456789";
|
|
|
|
|
std::string specialStr = "!@#$%^&*()_+=-`~[]{}|':;/?<,>.\\\"";
|
|
|
|
|
bool bHasUpperChar = false;
|
|
|
|
|
bool bHasLowerChar = false;
|
|
|
|
|
bool bHasDigit = false;
|
|
|
|
|
bool bHasSpecial = false;
|
|
|
|
|
// 字符不能超出以上范围
|
|
|
|
|
for(int i=0; i<m_advancePwd.length(); i++)
|
|
|
|
|
{
|
|
|
|
|
bool bUpperChar = (upperCharStr.find(m_advancePwd.at(i)) != std::string::npos);
|
|
|
|
|
bool bLowerChar = (lowerCharStr.find(m_advancePwd.at(i)) != std::string::npos);
|
|
|
|
|
bool bDigit = (digitStr.find(m_advancePwd.at(i)) != std::string::npos);
|
|
|
|
|
bool bSpecial = (specialStr.find(m_advancePwd.at(i)) != std::string::npos);
|
|
|
|
|
if(!bUpperChar && !bLowerChar && !bDigit && !bSpecial)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!bHasUpperChar && bUpperChar) bHasUpperChar = true;
|
|
|
|
|
if(!bHasLowerChar && bLowerChar) bHasLowerChar = true;
|
|
|
|
|
if(!bHasDigit && bDigit) bHasDigit = true;
|
|
|
|
|
if(!bHasSpecial && bSpecial) bHasSpecial = true;
|
|
|
|
|
}
|
|
|
|
|
if(!bHasUpperChar || !bHasLowerChar || !bHasDigit || !bHasSpecial)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Auth::bIsValidate()
|
|
|
|
|
{
|
|
|
|
|
if(!checkEncryptFlag())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!checkProductType())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!checkDate())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!checkTimes())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if(!checkAdvancePwd())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|