#include "Auth.h" #include #include "Utils.h" #include #include #include 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