You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
10 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}