smclass.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. #include "smclass.h"
  2. #include <QCoreApplication>
  3. #include <QProcess>
  4. #include <QFile>
  5. #include <QDebug>
  6. #define MAX_KEY_LEN 256
  7. #define MAX_MSG_LEN 512
  8. #ifdef __unix
  9. #define memcpy_s(dest, dst_size, src, src_size) memcpy((dest), (src), (src_size))
  10. #endif // __unit
  11. SMClass* SMClass::s_inst = nullptr;
  12. QMutex SMClass::s_mtx;
  13. SMClass* SMClass::Instance()
  14. {
  15. if (nullptr == s_inst) {
  16. QMutexLocker locker(&s_mtx);
  17. if (nullptr == s_inst) {
  18. s_inst = new SMClass();
  19. }
  20. }
  21. return s_inst;
  22. }
  23. SMClass::SMClass() : m_plib(nullptr)
  24. {
  25. Release();
  26. #ifdef __unix
  27. m_plib = new QLibrary(QCoreApplication::applicationDirPath() + "/libSM_Dll.so");
  28. #else
  29. m_plib = new QLibrary("libSM_Dll.dll");
  30. #endif
  31. LoadFunc();
  32. }
  33. SMClass::~SMClass()
  34. {
  35. if (m_plib->isLoaded()) {
  36. m_plib->unload();
  37. }
  38. if (nullptr != m_plib) {
  39. delete m_plib;
  40. }
  41. }
  42. void SMClass::Release()
  43. {
  44. m_pfCreateK = nullptr;
  45. m_pfPubKey = nullptr;
  46. m_pfPubKeyASN1 = nullptr;
  47. m_pfPubKey2Pem = nullptr;
  48. m_pfSetPubKey = nullptr;
  49. m_pfEncRaw = nullptr;
  50. m_pfDecRaw = nullptr;
  51. m_pfDecrypt = nullptr;
  52. m_pfEncrypt = nullptr;
  53. m_pfSignature = nullptr;
  54. m_pfVerifySign = nullptr;
  55. m_pfSm3 = nullptr;
  56. //m_pfSm3File = nullptr;
  57. m_pfSm4Encrypt = nullptr;
  58. m_pfSm4Decrypt = nullptr;
  59. m_pfSm4RandKey = nullptr;
  60. m_pfSm4Dec = nullptr;
  61. m_pfSm4Enc = nullptr;
  62. m_pfSm4EncEcb = nullptr;
  63. m_pfSm4DecEcb = nullptr;
  64. m_pfSm4EncCbc = nullptr;
  65. m_pfSm4DecCbc = nullptr;
  66. }
  67. void SMClass::LoadFunc()
  68. {
  69. m_pfCreateK = (psm2CreateKey)m_plib->resolve("sm2_create_key");
  70. m_pfPubKey = (psm2PublicKey)m_plib->resolve("sm2_public_key");
  71. m_pfPubKeyASN1 = (psm2PublicKeyASN1)m_plib->resolve("sm2_public_key_asn1");
  72. m_pfPubKey2Pem = (psm2PublicKeyToPem)m_plib->resolve("sm2_public_key_to_pem");
  73. m_pfSetPubKey = (psm2SetPublicKey)m_plib->resolve("sm2_set_public_key");
  74. m_pfEncRaw = (psm2EncryptRaw)m_plib->resolve("sm2_encrypt_raw");
  75. m_pfDecRaw = (psm2DecryptRaw)m_plib->resolve("sm2_decrypt_raw");
  76. m_pfDecrypt = (psm2DecryptASN1)m_plib->resolve("sm2_decrypt_asn1");
  77. m_pfEncrypt = (psm2EncryptASN1)m_plib->resolve("sm2_encrypt_asn1");
  78. m_pfSignature = (psm2Signature)m_plib->resolve("sm2_signature");
  79. m_pfVerifySign = (psm2VerifySign)m_plib->resolve("sm2_verify_sign");
  80. m_pfSm3 = (psm3)m_plib->resolve("sm3");
  81. //m_pfSm3File = (psm3_file)m_plib->resolve("sm3_file");
  82. m_pfSm4Encrypt = (psm4Encrypt)m_plib->resolve("sm4_doencrypt");
  83. m_pfSm4Decrypt = (psm4Decrypt)m_plib->resolve("sm4_dodecrypt");
  84. m_pfSm4RandKey = (psm4RandKey)m_plib->resolve("sm4_rand_key");
  85. m_pfSm4Dec = (psm4SetKeyDec)m_plib->resolve("sm4_setkey_dec");
  86. m_pfSm4Enc = (psm4SetKeyEnc)m_plib->resolve("sm4_setkey_enc");
  87. m_pfSm4EncEcb = (psm4EncryptEcb)m_plib->resolve("sm4_encrypt_ecb");
  88. m_pfSm4DecEcb = (psm4DecryptEcb)m_plib->resolve("sm4_decrypt_ecb");
  89. m_pfSm4EncCbc = (psm4EncryptCbc)m_plib->resolve("sm4_encrypt_cbc");
  90. m_pfSm4DecCbc = (psm4DecryptCbc)m_plib->resolve("sm4_decrypt_cbc");
  91. }
  92. bool SMClass::Sm2CreateKey(sm2_context* ctx)
  93. {
  94. if (nullptr == m_pfCreateK) {
  95. qDebug() << "sm2_create_key接口未加载。";
  96. return false;
  97. }
  98. return m_pfCreateK(ctx);
  99. }
  100. bool SMClass::Sm2PublicKey(sm2_context* ctx, QString& key)
  101. {
  102. if (nullptr == m_pfPubKey) {
  103. qDebug() << "sm2_public_key接口未加载。";
  104. return false;
  105. }
  106. uint8_t tmpKey[130]{0};
  107. bool bRet = m_pfPubKey(ctx, tmpKey);
  108. key = QString::fromStdString(std::string((char*)tmpKey, sizeof(tmpKey)));
  109. return bRet;
  110. }
  111. bool SMClass::Sm2PublicKeyASN1(sm2_context* ctx, QString& key)
  112. {
  113. if (nullptr == m_pfPubKeyASN1) {
  114. qDebug() << "sm2_public_key_asn1接口未加载。";
  115. return false;
  116. }
  117. uint8_t tmpKey[MAX_KEY_LEN]{0};
  118. size_t len = sizeof(tmpKey);
  119. bool bRet = m_pfPubKeyASN1(ctx, tmpKey, &len);
  120. key = QString::fromStdString(std::string((char*)tmpKey, len));
  121. return bRet;
  122. }
  123. bool SMClass::Sm2PublicKey2Pem(sm2_context* ctx, const QString& path)
  124. {
  125. if (nullptr == m_pfPubKey2Pem) {
  126. qDebug() << "sm2_public_key_to_pem接口未加载。";
  127. return false;
  128. }
  129. auto str = path.toStdString();// QString的size不考虑编码
  130. return m_pfPubKey2Pem(ctx, str.c_str(), str.size());
  131. }
  132. bool SMClass::Sm2SetPublicKey(sm2_context* ctx, int mode, const QString& data)
  133. {
  134. if (nullptr == m_pfSetPubKey) {
  135. qDebug() << "sm2_set_public_key接口未加载。";
  136. return false;
  137. }
  138. bool bRet = false;
  139. if (2 != mode) {
  140. bRet = m_pfSetPubKey(ctx, mode, (const uint8_t*)data.toStdString().c_str(), data.toStdString().size());
  141. } else {
  142. // 读取pem文件
  143. auto str = data.toStdString();
  144. bRet = m_pfSetPubKey(ctx, mode, (uint8_t*)str.c_str(), str.size());
  145. }
  146. return bRet;
  147. }
  148. bool SMClass::Sm2EncryptRaw(sm2_context* ctx, int mode, const QString& msg, QString& output)
  149. {
  150. if (nullptr == m_pfEncRaw) {
  151. qDebug() << "sm2_encrypt_raw接口未加载。";
  152. return false;
  153. }
  154. uint8_t tmpOut[MAX_MSG_LEN]{0};
  155. size_t len = MAX_MSG_LEN;
  156. auto str = msg.toStdString();
  157. bool bRet = m_pfEncRaw(ctx, mode, (uint8_t*)(str.c_str()), str.size(), tmpOut, &len);
  158. output = QString::fromStdString(std::string((char*)tmpOut, len));
  159. return bRet;
  160. }
  161. bool SMClass::Sm2DecryptRaw(sm2_context* ctx, int mode, const QString& msg, QString& output)
  162. {
  163. if (nullptr == m_pfDecRaw) {
  164. qDebug() << "sm2_decrypt_raw接口未加载。";
  165. return false;
  166. }
  167. uint8_t tmpOut[255]{0};
  168. size_t outlen = 255;
  169. bool bRet = m_pfDecRaw(ctx, mode, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &outlen);
  170. output = QString::fromStdString(std::string((char*)tmpOut, outlen));
  171. return bRet;
  172. }
  173. bool SMClass::Sm2EncryptASN1(sm2_context* ctx, const QString& msg, QString& output)
  174. {
  175. if (nullptr == m_pfEncrypt) {
  176. qDebug() << "sm2_encrypt_asn1接口未加载。";
  177. return false;
  178. }
  179. uint8_t tmpOut[MAX_MSG_LEN]{0};
  180. size_t len = MAX_MSG_LEN;
  181. auto str = msg.toStdString();
  182. bool bRet = m_pfEncrypt(ctx, (uint8_t*)str.c_str(), str.size(), tmpOut, &len);
  183. output = QString::fromStdString(std::string((char*)tmpOut, len));
  184. return bRet;
  185. }
  186. bool SMClass::Sm2DecryptASN1(sm2_context* ctx, const QString& msg, QString& output)
  187. {
  188. if (nullptr == m_pfDecrypt) {
  189. qDebug() << "sm2_decrypt_asn1接口未加载。";
  190. return false;
  191. }
  192. uint8_t tmpOut[MAX_MSG_LEN]{0};
  193. size_t outlen = MAX_MSG_LEN;
  194. bool bRet = m_pfDecrypt(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &outlen);
  195. output = QString::fromStdString(std::string((char*)tmpOut));
  196. return bRet;
  197. }
  198. bool SMClass::Sm2Signature(sm2_context* ctx, const QString& msg, QString& sign)
  199. {
  200. if (nullptr == m_pfSignature) {
  201. qDebug() << "sm2_signature接口未加载。";
  202. return false;
  203. }
  204. uint8_t tmpOut[366]{0};
  205. size_t len = 366;
  206. bool bRet = m_pfSignature(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), tmpOut, &len);
  207. sign = QString::fromStdString(std::string((char*)tmpOut, len));
  208. return bRet;
  209. }
  210. bool SMClass::Sm2VerifySign(sm2_context* ctx, const QString& msg, const QString& sign)
  211. {
  212. if (nullptr == m_pfVerifySign) {
  213. qDebug() << "sm2_verify_sign接口未加载。";
  214. return false;
  215. }
  216. bool bRet = m_pfVerifySign(ctx, (uint8_t*)msg.toStdString().c_str(), msg.toStdString().size(), (uint8_t*)sign.toStdString().c_str(), sign.toStdString().size());
  217. return bRet;
  218. }
  219. void SMClass::Sm3Hash(const QString& input, QString& output)
  220. {
  221. if (nullptr == m_pfSm3) {
  222. qDebug() << "sm3接口未加载。";
  223. return;
  224. }
  225. #ifdef Q_OS_LINUX
  226. ExeSm3Hash(input, output);
  227. #else
  228. sm3(input, output);
  229. #endif
  230. }
  231. int SMClass::Sm4Encrypt(const QString& key, const QString& input, QString& output)
  232. {
  233. if (nullptr == m_pfSm4Encrypt) {
  234. qDebug() << "sm4_encrypt接口未加载";
  235. return 0;
  236. }
  237. #ifdef Q_OS_LINUX
  238. ExeSm4Encrypt(key, input, output);
  239. return output.length();
  240. #else
  241. return sm4Enc(key, input, output);
  242. #endif
  243. }
  244. int SMClass::Sm4Decrypt(const QString& key, const QString &input, QString &output)
  245. {
  246. if (nullptr == m_pfSm4Decrypt) {
  247. qDebug() << "sm4_decrypt接口未加载";
  248. return 0;
  249. }
  250. #ifdef Q_OS_LINUX
  251. ExeSm4Decrypt(key, input, output);
  252. return output.length();
  253. #else
  254. return sm4Dec(key, input, output);
  255. #endif
  256. }
  257. void SMClass::Sm4RandKey(QString& key)
  258. {
  259. if (nullptr == m_pfSm4RandKey) {
  260. qDebug() << "sm4_rand_key接口未加载。";
  261. return;
  262. }
  263. uint8_t tmpKey[32]{0};
  264. m_pfSm4RandKey(tmpKey, sizeof(tmpKey));
  265. key = QString::fromStdString(std::string((char*)tmpKey, sizeof(tmpKey)));
  266. }
  267. void SMClass::Sm4KeyEncrypt(sm4_context* ctx, const QString& key)
  268. {
  269. if (nullptr == m_pfSm4Enc) {
  270. qDebug() << "sm4_setkey_enc接口未加载。";
  271. return;
  272. }
  273. uint8_t aKey[32]{0};
  274. memcpy_s(aKey, sizeof(aKey), key.toStdString().c_str(), key.toStdString().size());
  275. m_pfSm4Enc(ctx, aKey);
  276. }
  277. void SMClass::Sm4KeyDecrypt(sm4_context* ctx, const QString& key)
  278. {
  279. if (nullptr == m_pfSm4Dec) {
  280. qDebug() << "sm4_setkey_dec接口未加载。";
  281. return;
  282. }
  283. uint8_t aKey[32]{0};
  284. memcpy_s(aKey, sizeof(aKey), key.toStdString().c_str(), key.toStdString().size());
  285. m_pfSm4Dec(ctx, aKey);
  286. }
  287. int SMClass::Sm4EncryptEcb(sm4_context *ctx, const QString& input, QString& output)
  288. {
  289. if (nullptr == m_pfSm4EncEcb) {
  290. qDebug() << "sm4_encrypt_ecb接口未加载。";
  291. return 0;
  292. }
  293. auto str = input.toStdString();
  294. size_t inlen = input.toStdString().size();
  295. pUchar pOut(new uint8_t[MAX_MSG_LEN]{0});
  296. int outlen = m_pfSm4EncEcb(ctx, (uint8_t*)input.toStdString().c_str(), inlen, pOut.get());
  297. output = QString::fromStdString(std::string((char*)pOut.get(), outlen));
  298. return outlen;
  299. }
  300. int SMClass::Sm4DecryptEcb(sm4_context *ctx, const QString& input, QString& output)
  301. {
  302. if (nullptr == m_pfSm4DecEcb) {
  303. qDebug() << "sm4_decrypt_ecb接口未加载。";
  304. return 0;
  305. }
  306. if (input.size() % 16 != 0) return 0;
  307. pUchar pOut(new unsigned char[MAX_MSG_LEN]{0});
  308. int outlen = m_pfSm4DecEcb(ctx, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get());
  309. if (outlen < 0) return 0;
  310. output = QString::fromStdString(std::string((char*)pOut.get(), outlen));
  311. return outlen;
  312. }
  313. int SMClass::Sm4EncryptCbc(sm4_context *ctx, const QString& iv, const QString& input, QString& output)
  314. {
  315. if (nullptr == m_pfSm4EncCbc) {
  316. qDebug() << "sm4_encrypt_cbc接口未加载。";
  317. return 0;
  318. }
  319. pUchar pOut(new uint8_t[MAX_MSG_LEN]{0});
  320. uint8_t arrIv[32]{0};
  321. memcpy_s(arrIv, sizeof(arrIv), iv.toStdString().c_str(), iv.toStdString().size());
  322. int outlen = m_pfSm4EncCbc(ctx, arrIv, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get());
  323. output = QString::fromStdString(std::string((char*)pOut.get(), outlen));
  324. return outlen;
  325. }
  326. int SMClass::Sm4DecryptCbc(sm4_context *ctx, const QString& iv, const QString& input, QString& output)
  327. {
  328. if (nullptr == m_pfSm4DecCbc) {
  329. qDebug() << "sm4_decrypt_cbc接口未加载。";
  330. return 0;
  331. }
  332. uint8_t arrIv[32]{0};
  333. memcpy_s(arrIv, sizeof(arrIv), iv.toStdString().c_str(), iv.toStdString().size());
  334. pUchar pOut(new unsigned char[MAX_MSG_LEN]{0});
  335. int outlen = m_pfSm4DecCbc(ctx, arrIv, (uint8_t*)input.toStdString().c_str(), input.toStdString().size(), pOut.get());
  336. if (outlen < 0) return 0;
  337. output = QString::fromStdString(std::string((char*)pOut.get(), outlen));
  338. return outlen;
  339. }
  340. void SMClass::ExeSm3Hash(const QString& input, QString& out)
  341. {
  342. QProcess process;
  343. process.start("./SM_Dll", QStringList() << "sm3" << input);
  344. if (process.waitForStarted()) {
  345. if (process.waitForFinished()) {
  346. out = process.readAllStandardOutput();
  347. }
  348. }
  349. }
  350. int SMClass::ExeSm4Encrypt(const QString& key, const QString& input, QString& out)
  351. {
  352. QProcess process;
  353. process.start(QString("./SM_Dll"), QStringList() << "sm4Enc" << key << input);
  354. if (process.waitForStarted()) {
  355. if (process.waitForFinished()) {
  356. out = process.readAllStandardOutput();
  357. return !out.isEmpty();
  358. }
  359. }
  360. return 0;
  361. }
  362. int SMClass::ExeSm4Decrypt(const QString& key, const QString& input, QString& out)
  363. {
  364. QProcess process;
  365. process.start("./SM_Dll", QStringList() << "sm4Dec" << key << input);
  366. if (process.waitForStarted()) {
  367. if (process.waitForFinished()) {
  368. out = process.readAllStandardOutput();
  369. return !out.isEmpty();
  370. }
  371. }
  372. return 0;
  373. }
  374. void SMClass::sm3(const QString& input, QString& output)
  375. {
  376. auto str = input.toStdString();
  377. uint8_t out[64]{0};
  378. m_pfSm3((uint8_t*)str.c_str(), str.size(), out);
  379. output = QString::fromStdString(std::string((char*)out, sizeof(out)));
  380. }
  381. int SMClass::sm4Enc(const QString& key, const QString& input, QString& output)
  382. {
  383. char out[MAX_MSG_LEN]{0};
  384. size_t outlen = MAX_MSG_LEN; // 真实大小
  385. outlen = m_pfSm4Encrypt(key.toStdString().c_str(), key.toStdString().size(), input.toStdString().c_str(), input.toStdString().size(), out, &outlen);
  386. output = QString::fromStdString(std::string(out, outlen));
  387. return outlen;
  388. }
  389. int SMClass::sm4Dec(const QString& key, const QString& input, QString& output)
  390. {
  391. char out[MAX_MSG_LEN]{0};
  392. size_t outlen = MAX_MSG_LEN; // 真实大小
  393. outlen = m_pfSm4Decrypt(key.toStdString().c_str(), key.toStdString().size(), input.toStdString().c_str(), input.toStdString().size(), out, &outlen);
  394. output = QString::fromStdString(std::string(out, outlen));
  395. return outlen;
  396. }
  397. QString SMClass::uchartoHex(uint8_t* input, size_t size) {
  398. if (nullptr == input) return QString();
  399. std::unique_ptr<char[]> output(new char[size * 2 + 1]{0});
  400. for (size_t i = 0; i < size; ++i) {
  401. sprintf(&output[i * 2], "%02x", input[i]);
  402. }
  403. QString ret(output.get());
  404. return ret.toUpper();
  405. }
  406. std::unique_ptr<uint8_t[]> SMClass::hextoUchar(const QString& hexString, size_t& size) {
  407. size_t length = hexString.size();
  408. size = 0;
  409. if (length % 2 != 0) {
  410. return std::unique_ptr<uint8_t[]>(); // 非偶数长度的十六进制字符串无法转换
  411. }
  412. size = length / 2;
  413. std::string pHex = hexString.toStdString();
  414. std::unique_ptr<uint8_t[]> output(new unsigned char[size]{0});
  415. try {
  416. for (size_t i = 0; i < size; ++i) {
  417. int value = 0;
  418. sscanf(&pHex[i * 2], "%2x", &value);
  419. output[i] = (unsigned char)value;
  420. }
  421. } catch(...) {
  422. qDebug() << "从Hex string到uint8_t*转换失败!";
  423. }
  424. return std::move(output);
  425. }
  426. void SMClass::readResultAndDelete(const QString &fileName, QString &out)
  427. {
  428. QFile tmpF(fileName);
  429. if (tmpF.open(QIODevice::ReadOnly)) {
  430. out = tmpF.readAll();
  431. tmpF.close();
  432. }
  433. //QFile::remove(fileName);
  434. }