#include "smclass.h" #include #include #include #include #define MAX_KEY_LEN 256 #define MAX_MSG_LEN 512 #ifdef __unix #define memcpy_s(dest, dst_size, src, src_size) memcpy((dest), (src), (src_size)) #endif // __unit SMClass* SMClass::s_inst = nullptr; QMutex SMClass::s_mtx; SMClass* SMClass::Instance() { if (nullptr == s_inst) { QMutexLocker locker(&s_mtx); if (nullptr == s_inst) { s_inst = new SMClass(); } } return s_inst; } SMClass::SMClass() : m_plib(nullptr) { Release(); #ifdef __unix m_plib = new QLibrary(QCoreApplication::applicationDirPath() + "/libSM_Dll.so"); #else m_plib = new QLibrary("libSM_Dll.dll"); #endif LoadFunc(); } SMClass::~SMClass() { if (m_plib->isLoaded()) { m_plib->unload(); } if (nullptr != m_plib) { delete m_plib; } } void SMClass::Release() { m_pfCreateK = nullptr; m_pfPubKey = nullptr; m_pfPubKeyASN1 = nullptr; m_pfPubKey2Pem = nullptr; m_pfSetPubKey = nullptr; m_pfEncRaw = nullptr; m_pfDecRaw = nullptr; m_pfDecrypt = nullptr; m_pfEncrypt = nullptr; m_pfSignature = nullptr; m_pfVerifySign = nullptr; m_pfSm3 = nullptr; //m_pfSm3File = nullptr; m_pfSm4Encrypt = nullptr; m_pfSm4Decrypt = nullptr; m_pfSm4RandKey = nullptr; m_pfSm4Dec = nullptr; m_pfSm4Enc = nullptr; m_pfSm4EncEcb = nullptr; m_pfSm4DecEcb = nullptr; m_pfSm4EncCbc = nullptr; m_pfSm4DecCbc = nullptr; } void SMClass::LoadFunc() { m_pfCreateK = (psm2CreateKey)m_plib->resolve("sm2_create_key"); m_pfPubKey = (psm2PublicKey)m_plib->resolve("sm2_public_key"); m_pfPubKeyASN1 = (psm2PublicKeyASN1)m_plib->resolve("sm2_public_key_asn1"); m_pfPubKey2Pem = (psm2PublicKeyToPem)m_plib->resolve("sm2_public_key_to_pem"); m_pfSetPubKey = (psm2SetPublicKey)m_plib->resolve("sm2_set_public_key"); m_pfEncRaw = (psm2EncryptRaw)m_plib->resolve("sm2_encrypt_raw"); m_pfDecRaw = (psm2DecryptRaw)m_plib->resolve("sm2_decrypt_raw"); m_pfDecrypt = (psm2DecryptASN1)m_plib->resolve("sm2_decrypt_asn1"); m_pfEncrypt = (psm2EncryptASN1)m_plib->resolve("sm2_encrypt_asn1"); m_pfSignature = (psm2Signature)m_plib->resolve("sm2_signature"); m_pfVerifySign = (psm2VerifySign)m_plib->resolve("sm2_verify_sign"); m_pfSm3 = (psm3)m_plib->resolve("sm3"); //m_pfSm3File = (psm3_file)m_plib->resolve("sm3_file"); m_pfSm4Encrypt = (psm4Encrypt)m_plib->resolve("sm4_doencrypt"); m_pfSm4Decrypt = (psm4Decrypt)m_plib->resolve("sm4_dodecrypt"); m_pfSm4RandKey = (psm4RandKey)m_plib->resolve("sm4_rand_key"); m_pfSm4Dec = (psm4SetKeyDec)m_plib->resolve("sm4_setkey_dec"); m_pfSm4Enc = (psm4SetKeyEnc)m_plib->resolve("sm4_setkey_enc"); m_pfSm4EncEcb = (psm4EncryptEcb)m_plib->resolve("sm4_encrypt_ecb"); m_pfSm4DecEcb = (psm4DecryptEcb)m_plib->resolve("sm4_decrypt_ecb"); m_pfSm4EncCbc = (psm4EncryptCbc)m_plib->resolve("sm4_encrypt_cbc"); m_pfSm4DecCbc = (psm4DecryptCbc)m_plib->resolve("sm4_decrypt_cbc"); } bool SMClass::Sm2CreateKey(sm2_context* ctx) { if (nullptr == m_pfCreateK) { qDebug() << "sm2_create_key接口未加载。"; return false; } return m_pfCreateK(ctx); } bool SMClass::Sm2PublicKey(sm2_context* ctx, QString& key) { if (nullptr == m_pfPubKey) { qDebug() << "sm2_public_key接口未加载。"; return false; } uint8_t tmpKey[130]{0}; bool bRet = m_pfPubKey(ctx, tmpKey); key = QString::fromStdString(std::string((char*)tmpKey, sizeof(tmpKey))); return bRet; } bool SMClass::Sm2PublicKeyASN1(sm2_context* ctx, QString& key) { if (nullptr == m_pfPubKeyASN1) { qDebug() << "sm2_public_key_asn1接口未加载。"; return false; } uint8_t tmpKey[MAX_KEY_LEN]{0}; size_t len = sizeof(tmpKey); bool bRet = m_pfPubKeyASN1(ctx, tmpKey, &len); key = QString::fromStdString(std::string((char*)tmpKey, len)); return bRet; } bool SMClass::Sm2PublicKey2Pem(sm2_context* ctx, const QString& path) { if (nullptr == m_pfPubKey2Pem) { qDebug() << "sm2_public_key_to_pem接口未加载。"; return false; } auto str = path.toStdString();// QString的size不考虑编码 return m_pfPubKey2Pem(ctx, str.c_str(), str.size()); } bool SMClass::Sm2SetPublicKey(sm2_context* ctx, int mode, const QString& data) { if (nullptr == m_pfSetPubKey) { qDebug() << "sm2_set_public_key接口未加载。"; return false; } bool bRet = false; if (2 != mode) { bRet = m_pfSetPubKey(ctx, mode, (const uint8_t*)data.toStdString().c_str(), data.toStdString().size()); } else { // 读取pem文件 auto str = data.toStdString(); bRet = m_pfSetPubKey(ctx, mode, (uint8_t*)str.c_str(), str.size()); } return bRet; } bool SMClass::Sm2EncryptRaw(sm2_context* ctx, int mode, const QString& msg, QString& output) { if (nullptr == m_pfEncRaw) { qDebug() << "sm2_encrypt_raw接口未加载。"; return false; } uint8_t tmpOut[MAX_MSG_LEN]{0}; size_t len = MAX_MSG_LEN; auto str = msg.toStdString(); bool bRet = m_pfEncRaw(ctx, mode, (uint8_t*)(str.c_str()), str.size(), tmpOut, &len); output = QString::fromStdString(std::string((char*)tmpOut, len)); return bRet; } bool SMClass::Sm2DecryptRaw(sm2_context* ctx, int mode, const QString& msg, QString& output) { if (nullptr == m_pfDecRaw) { qDebug() << "sm2_decrypt_raw接口未加载。"; return false; } uint8_t tmpOut[255]{0}; size_t outlen = 255; bool bRet = m_pfDecRaw(ctx, mode, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &outlen); output = QString::fromStdString(std::string((char*)tmpOut, outlen)); return bRet; } bool SMClass::Sm2EncryptASN1(sm2_context* ctx, const QString& msg, QString& output) { if (nullptr == m_pfEncrypt) { qDebug() << "sm2_encrypt_asn1接口未加载。"; return false; } uint8_t tmpOut[MAX_MSG_LEN]{0}; size_t len = MAX_MSG_LEN; auto str = msg.toStdString(); bool bRet = m_pfEncrypt(ctx, (uint8_t*)str.c_str(), str.size(), tmpOut, &len); output = QString::fromStdString(std::string((char*)tmpOut, len)); return bRet; } bool SMClass::Sm2DecryptASN1(sm2_context* ctx, const QString& msg, QString& output) { if (nullptr == m_pfDecrypt) { qDebug() << "sm2_decrypt_asn1接口未加载。"; return false; } uint8_t tmpOut[MAX_MSG_LEN]{0}; size_t outlen = MAX_MSG_LEN; bool bRet = m_pfDecrypt(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &outlen); output = QString::fromStdString(std::string((char*)tmpOut)); return bRet; } bool SMClass::Sm2Signature(sm2_context* ctx, const QString& msg, QString& sign) { if (nullptr == m_pfSignature) { qDebug() << "sm2_signature接口未加载。"; return false; } uint8_t tmpOut[366]{0}; size_t len = 366; bool bRet = m_pfSignature(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &len); sign = QString::fromStdString(std::string((char*)tmpOut, len)); return bRet; } bool SMClass::Sm2VerifySign(sm2_context* ctx, const QString& msg, const QString& sign) { if (nullptr == m_pfVerifySign) { qDebug() << "sm2_verify_sign接口未加载。"; return false; } bool bRet = m_pfVerifySign(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), (uint8_t*)sign.toStdString().c_str(), sign.toStdString().size()); return bRet; } void SMClass::Sm3Hash(const QString& input, QString& output) { if (nullptr == m_pfSm3) { qDebug() << "sm3接口未加载。"; return; } #ifdef Q_OS_LINUX ExeSm3Hash(input, output); #else sm3(input, output); #endif } int SMClass::Sm4Encrypt(const QString& key, const QString& input, QString& output) { if (nullptr == m_pfSm4Encrypt) { qDebug() << "sm4_encrypt接口未加载"; return 0; } #ifdef Q_OS_LINUX ExeSm4Encrypt(key, input, output); return output.length(); #else return sm4Enc(key, input, output); #endif } int SMClass::Sm4Decrypt(const QString& key, const QString &input, QString &output) { if (nullptr == m_pfSm4Decrypt) { qDebug() << "sm4_decrypt接口未加载"; return 0; } #ifdef Q_OS_LINUX ExeSm4Decrypt(key, input, output); return output.length(); #else return sm4Dec(key, input, output); #endif } void SMClass::Sm4RandKey(QString& key) { if (nullptr == m_pfSm4RandKey) { qDebug() << "sm4_rand_key接口未加载。"; return; } uint8_t tmpKey[32]{0}; m_pfSm4RandKey(tmpKey, sizeof(tmpKey)); key = QString::fromStdString(std::string((char*)tmpKey, sizeof(tmpKey))); } void SMClass::Sm4KeyEncrypt(sm4_context* ctx, const QString& key) { if (nullptr == m_pfSm4Enc) { qDebug() << "sm4_setkey_enc接口未加载。"; return; } uint8_t aKey[32]{0}; memcpy_s(aKey, sizeof(aKey), key.toStdString().c_str(), key.toStdString().size()); m_pfSm4Enc(ctx, aKey); } void SMClass::Sm4KeyDecrypt(sm4_context* ctx, const QString& key) { if (nullptr == m_pfSm4Dec) { qDebug() << "sm4_setkey_dec接口未加载。"; return; } uint8_t aKey[32]{0}; memcpy_s(aKey, sizeof(aKey), key.toStdString().c_str(), key.toStdString().size()); m_pfSm4Dec(ctx, aKey); } int SMClass::Sm4EncryptEcb(sm4_context *ctx, const QString& input, QString& output) { if (nullptr == m_pfSm4EncEcb) { qDebug() << "sm4_encrypt_ecb接口未加载。"; return 0; } auto str = input.toStdString(); size_t inlen = input.toStdString().size(); pUchar pOut(new uint8_t[MAX_MSG_LEN]{0}); int outlen = m_pfSm4EncEcb(ctx, (uint8_t*)input.toStdString().c_str(), inlen, pOut.get()); output = QString::fromStdString(std::string((char*)pOut.get(), outlen)); return outlen; } int SMClass::Sm4DecryptEcb(sm4_context *ctx, const QString& input, QString& output) { if (nullptr == m_pfSm4DecEcb) { qDebug() << "sm4_decrypt_ecb接口未加载。"; return 0; } if (input.size() % 16 != 0) return 0; pUchar pOut(new unsigned char[MAX_MSG_LEN]{0}); int outlen = m_pfSm4DecEcb(ctx, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get()); if (outlen < 0) return 0; output = QString::fromStdString(std::string((char*)pOut.get(), outlen)); return outlen; } int SMClass::Sm4EncryptCbc(sm4_context *ctx, const QString& iv, const QString& input, QString& output) { if (nullptr == m_pfSm4EncCbc) { qDebug() << "sm4_encrypt_cbc接口未加载。"; return 0; } pUchar pOut(new uint8_t[MAX_MSG_LEN]{0}); uint8_t arrIv[32]{0}; memcpy_s(arrIv, sizeof(arrIv), iv.toStdString().c_str(), iv.toStdString().size()); int outlen = m_pfSm4EncCbc(ctx, arrIv, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get()); output = QString::fromStdString(std::string((char*)pOut.get(), outlen)); return outlen; } int SMClass::Sm4DecryptCbc(sm4_context *ctx, const QString& iv, const QString& input, QString& output) { if (nullptr == m_pfSm4DecCbc) { qDebug() << "sm4_decrypt_cbc接口未加载。"; return 0; } uint8_t arrIv[32]{0}; memcpy_s(arrIv, sizeof(arrIv), iv.toStdString().c_str(), iv.toStdString().size()); pUchar pOut(new unsigned char[MAX_MSG_LEN]{0}); int outlen = m_pfSm4DecCbc(ctx, arrIv, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get()); if (outlen < 0) return 0; output = QString::fromStdString(std::string((char*)pOut.get(), outlen)); return outlen; } void SMClass::ExeSm3Hash(const QString& input, QString& out) { QProcess process; process.start("./SM_Dll", QStringList() << "sm3" << input); if (process.waitForStarted()) { if (process.waitForFinished()) { out = process.readAllStandardOutput(); } } } int SMClass::ExeSm4Encrypt(const QString& key, const QString& input, QString& out) { QProcess process; process.start(QString("./SM_Dll"), QStringList() << "sm4Enc" << key << input); if (process.waitForStarted()) { if (process.waitForFinished()) { out = process.readAllStandardOutput(); return !out.isEmpty(); } } return 0; } int SMClass::ExeSm4Decrypt(const QString& key, const QString& input, QString& out) { QProcess process; process.start("./SM_Dll", QStringList() << "sm4Dec" << key << input); if (process.waitForStarted()) { if (process.waitForFinished()) { out = process.readAllStandardOutput(); return !out.isEmpty(); } } return 0; } void SMClass::sm3(const QString& input, QString& output) { auto str = input.toStdString(); uint8_t out[64]{0}; m_pfSm3((uint8_t*)str.c_str(), str.size(), out); output = QString::fromStdString(std::string((char*)out, sizeof(out))); } int SMClass::sm4Enc(const QString& key, const QString& input, QString& output) { char out[MAX_MSG_LEN]{0}; size_t outlen = MAX_MSG_LEN; // 真实大小 outlen = m_pfSm4Encrypt(key.toStdString().c_str(), key.toStdString().size(), input.toStdString().c_str(), input.toStdString().size(), out, &outlen); output = QString::fromStdString(std::string(out, outlen)); return outlen; } int SMClass::sm4Dec(const QString& key, const QString& input, QString& output) { char out[MAX_MSG_LEN]{0}; size_t outlen = MAX_MSG_LEN; // 真实大小 outlen = m_pfSm4Decrypt(key.toStdString().c_str(), key.toStdString().size(), input.toStdString().c_str(), input.toStdString().size(), out, &outlen); output = QString::fromStdString(std::string(out, outlen)); return outlen; } QString SMClass::uchartoHex(uint8_t* input, size_t size) { if (nullptr == input) return QString(); std::unique_ptr output(new char[size * 2 + 1]{0}); for (size_t i = 0; i < size; ++i) { sprintf(&output[i * 2], "%02x", input[i]); } QString ret(output.get()); return ret.toUpper(); } std::unique_ptr SMClass::hextoUchar(const QString& hexString, size_t& size) { size_t length = hexString.size(); size = 0; if (length % 2 != 0) { return std::unique_ptr(); // 非偶数长度的十六进制字符串无法转换 } size = length / 2; std::string pHex = hexString.toStdString(); std::unique_ptr output(new unsigned char[size]{0}); try { for (size_t i = 0; i < size; ++i) { int value = 0; sscanf(&pHex[i * 2], "%2x", &value); output[i] = (unsigned char)value; } } catch(...) { qDebug() << "从Hex string到uint8_t*转换失败!"; } return std::move(output); } void SMClass::readResultAndDelete(const QString &fileName, QString &out) { QFile tmpF(fileName); if (tmpF.open(QIODevice::ReadOnly)) { out = tmpF.readAll(); tmpF.close(); } //QFile::remove(fileName); }