NavicatCrypto.hpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #pragma once
  2. #include "aes.h"
  3. #include "blowfish.h"
  4. #include "SHA1.h"
  5. #include <vector>
  6. class Navicat11Crypto {
  7. protected:
  8. BLOWFISH_KEY BlowfishKey;
  9. void BytesToHex(const void* src, size_t len, char* dst) {
  10. for (size_t i = 0; i < len; ++i) {
  11. char h = reinterpret_cast<const uint8_t*>(src)[i] >> 4;
  12. char l = reinterpret_cast<const uint8_t*>(src)[i] & 0x0F;
  13. h += h >= 10 ? 'A' - 10 : '0';
  14. l += l >= 10 ? 'A' - 10 : '0';
  15. dst[2 * i] = h;
  16. dst[2 * i + 1] = l;
  17. }
  18. }
  19. bool CheckHex(const char* src, size_t len) {
  20. if (len % 2 != 0)
  21. return false;
  22. for (size_t i = 0; i < len; i += 2) {
  23. char h = src[i];
  24. char l = src[i + 1];
  25. if (src[i] < '0' || src[i] > 'F')
  26. return false;
  27. if (src[i] < 'A' && src[i] > '9')
  28. return false;
  29. if (src[i + 1] < '0' || src[i + 1] > 'F')
  30. return false;
  31. if (src[i + 1] < 'A' && src[i + 1] > '9')
  32. return false;
  33. }
  34. return true;
  35. }
  36. void HexToBytes(const char* src, size_t len, void* dst) {
  37. for (size_t i = 0; i < len; i += 2) {
  38. uint8_t h = src[i];
  39. uint8_t l = src[i + 1];
  40. h -= h > '9' ? 'A' - 10 : '0';
  41. l -= l > '9' ? 'A' - 10 : '0';
  42. reinterpret_cast<uint8_t*>(dst)[i / 2] = (h << 4 )^ l;
  43. }
  44. }
  45. public:
  46. Navicat11Crypto() {
  47. const uint8_t DefaultKey[8] = {
  48. '3', 'D', 'C', '5', 'C', 'A', '3', '9'
  49. };
  50. SHA1_DIGEST KeyHash;
  51. accelc_SHA1(DefaultKey, sizeof(DefaultKey), &KeyHash);
  52. accelc_Blowfish_set_key(KeyHash.byte, sizeof(KeyHash), &BlowfishKey);
  53. }
  54. Navicat11Crypto(const void* srcBytes, size_t srclen) {
  55. if (srclen == 0)
  56. srclen = BLOWFISH_MIN_KEY_LENGTH;
  57. if (srclen > BLOWFISH_MAX_KEY_LENGTH)
  58. srclen = BLOWFISH_MAX_KEY_LENGTH;
  59. SHA1_DIGEST KeyHash;
  60. accelc_SHA1(srcBytes, srclen, &KeyHash);
  61. accelc_Blowfish_set_key(KeyHash.byte, sizeof(KeyHash), &BlowfishKey);
  62. }
  63. std::vector<char> EncryptString(const void* srcBytes, size_t srclen) {
  64. std::vector<char> ret;
  65. if (srclen == 0)
  66. return ret;
  67. ret.resize(srclen * 2 + 1);
  68. ret[srclen * 2] = 0;
  69. uint8_t CV[BLOWFISH_BLOCK_SIZE] = {
  70. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  71. };
  72. accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  73. const uint64_t* blocks = reinterpret_cast<const uint64_t*>(srcBytes);
  74. size_t blocks_len = srclen / BLOWFISH_BLOCK_SIZE;
  75. for (size_t i = 0; i < blocks_len; ++i) {
  76. union {
  77. uint8_t byte[8];
  78. uint64_t qword;
  79. } temp;
  80. temp.qword = blocks[i];
  81. temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
  82. accelc_Blowfish_encrypt(temp.byte, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  83. *reinterpret_cast<uint64_t*>(CV) ^= temp.qword;
  84. BytesToHex(temp.byte, 8, ret.data() + 16 * i);
  85. }
  86. if (srclen % BLOWFISH_BLOCK_SIZE) {
  87. accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  88. for (size_t i = 0; i < srclen % BLOWFISH_BLOCK_SIZE; ++i)
  89. CV[i] ^= reinterpret_cast<const uint8_t*>(blocks + blocks_len)[i];
  90. BytesToHex(CV, srclen % BLOWFISH_BLOCK_SIZE, ret.data() + 16 * blocks_len);
  91. }
  92. return ret;
  93. }
  94. std::vector<uint8_t> DecryptString(const char* srchex, size_t srclen) {
  95. std::vector<uint8_t> ret;
  96. if (CheckHex(srchex, srclen) == false)
  97. return ret;
  98. ret.resize(srclen / 2);
  99. uint8_t CV[BLOWFISH_BLOCK_SIZE] = {
  100. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  101. };
  102. accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  103. const char (*blocks)[16] = reinterpret_cast<const char (*)[16]>(srchex);
  104. size_t blocks_len = srclen / 16;
  105. for (size_t i = 0; i < blocks_len; ++i) {
  106. union {
  107. uint8_t byte[8];
  108. uint64_t qword;
  109. } temp, temp2;
  110. HexToBytes(blocks[i], 16, temp.byte);
  111. std::memcpy(temp2.byte, temp.byte, 8);
  112. accelc_Blowfish_decrypt(temp.byte, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  113. temp.qword ^= *reinterpret_cast<uint64_t*>(CV);
  114. *reinterpret_cast<uint64_t*>(ret.data() + 8 * i) = temp.qword;
  115. *reinterpret_cast<uint64_t*>(CV) ^= temp2.qword;
  116. }
  117. if (srclen % 16) {
  118. union {
  119. uint8_t byte[8];
  120. uint64_t qword;
  121. } temp = { };
  122. HexToBytes(blocks[blocks_len], srclen % 16, temp.byte);
  123. accelc_Blowfish_encrypt(CV, &BlowfishKey, BLOWFISH_BIG_ENDIAN);
  124. for (size_t i = 0; i < (srclen % 16) / 2; ++i)
  125. ret[blocks_len * 8 + i] = temp.byte[i] ^ CV[i];
  126. }
  127. return ret;
  128. }
  129. };
  130. class Navicat12Crypto : public Navicat11Crypto {
  131. protected:
  132. AES_KEY AES128Key;
  133. public:
  134. Navicat12Crypto() : Navicat11Crypto() {
  135. uint8_t DefaultKey[16] = {
  136. 'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y',
  137. 'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y'
  138. };
  139. accelc_AES128_set_key(DefaultKey, &AES128Key);
  140. }
  141. Navicat12Crypto(const void* srcBytes, size_t srclen) :
  142. Navicat11Crypto(srcBytes, srclen) {
  143. uint8_t DefaultKey[16] = {
  144. 'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y',
  145. 'l', 'i', 'b', 'c', 'c', 'k', 'e', 'y'
  146. };
  147. accelc_AES128_set_key(DefaultKey, &AES128Key);
  148. }
  149. std::vector<char> EncryptString(const void* srcBytes, size_t srclen) {
  150. std::vector<char> ret;
  151. if (srclen == 0)
  152. return ret;
  153. ret.resize((srclen / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE * 2);
  154. union {
  155. uint8_t byte[AES_BLOCK_SIZE];
  156. uint64_t qword[2];
  157. } CV = {
  158. 'l', 'i', 'b', 'c', 'c', 'i', 'v', ' ',
  159. 'l', 'i', 'b', 'c', 'c', 'i', 'v', ' '
  160. };
  161. const uint8_t (*blocks)[AES_BLOCK_SIZE] = reinterpret_cast<const uint8_t (*)[AES_BLOCK_SIZE]>(srcBytes);
  162. size_t blocks_len = srclen / AES_BLOCK_SIZE;
  163. for (size_t i = 0; i < blocks_len; ++i) {
  164. union {
  165. uint8_t byte[AES_BLOCK_SIZE];
  166. uint64_t qword[2];
  167. } temp;
  168. std::memcpy(temp.byte, blocks[i], AES_BLOCK_SIZE);
  169. temp.qword[0] ^= CV.qword[0];
  170. temp.qword[1] ^= CV.qword[1];
  171. accelc_AES128_encrypt(temp.byte, &AES128Key);
  172. BytesToHex(temp.byte, AES_BLOCK_SIZE, ret.data() + 2 * AES_BLOCK_SIZE * i);
  173. CV.qword[0] = temp.qword[0];
  174. CV.qword[1] = temp.qword[1];
  175. }
  176. uint8_t padding = AES_BLOCK_SIZE - srclen % AES_BLOCK_SIZE;
  177. union {
  178. uint8_t byte[AES_BLOCK_SIZE];
  179. uint64_t qword[2];
  180. } temp;
  181. std::memcpy(temp.byte, blocks[blocks_len], srclen % AES_BLOCK_SIZE);
  182. for (size_t i = srclen % AES_BLOCK_SIZE; i < AES_BLOCK_SIZE; ++i)
  183. temp.byte[i] = padding;
  184. temp.qword[0] ^= CV.qword[0];
  185. temp.qword[1] ^= CV.qword[1];
  186. accelc_AES128_encrypt(temp.byte, &AES128Key);
  187. BytesToHex(temp.byte, AES_BLOCK_SIZE, ret.data() + 2 * AES_BLOCK_SIZE * blocks_len);
  188. return ret;
  189. }
  190. std::vector<uint8_t> DecryptString(const char* srchex, size_t srclen) {
  191. std::vector<uint8_t> ret;
  192. if (srclen % (2 * AES_BLOCK_SIZE) != 0 || CheckHex(srchex, srclen) == false)
  193. return ret;
  194. ret.reserve(srclen / 2);
  195. ret.resize(srclen / 2 - AES_BLOCK_SIZE);
  196. union {
  197. uint8_t byte[AES_BLOCK_SIZE];
  198. uint64_t qword[2];
  199. } CV = {
  200. 'l', 'i', 'b', 'c', 'c', 'i', 'v', ' ',
  201. 'l', 'i', 'b', 'c', 'c', 'i', 'v', ' '
  202. };
  203. const char (*blocks)[2 * AES_BLOCK_SIZE] = reinterpret_cast<const char(*)[2 * AES_BLOCK_SIZE]>(srchex);
  204. size_t blocks_len = srclen / (2 * AES_BLOCK_SIZE);
  205. for (size_t i = 0; i < blocks_len; ++i) {
  206. union {
  207. uint8_t byte[AES_BLOCK_SIZE];
  208. uint64_t qword[2];
  209. } temp, NextVector;
  210. HexToBytes(blocks[i], 2 * AES_BLOCK_SIZE, temp.byte);
  211. std::memcpy(NextVector.byte, temp.byte, AES_BLOCK_SIZE);
  212. accelc_AES128_decrypt(temp.byte, &AES128Key);
  213. temp.qword[0] ^= CV.qword[0];
  214. temp.qword[1] ^= CV.qword[1];
  215. std::memcpy(ret.data() + AES_BLOCK_SIZE * i, temp.byte, AES_BLOCK_SIZE);
  216. std::memcpy(CV.byte, NextVector.byte, AES_BLOCK_SIZE);
  217. }
  218. union {
  219. uint8_t byte[AES_BLOCK_SIZE];
  220. uint64_t qword[2];
  221. } temp;
  222. HexToBytes(blocks[blocks_len], 2 * AES_BLOCK_SIZE, temp.byte);
  223. accelc_AES128_decrypt(temp.byte, &AES128Key);
  224. temp.qword[0] ^= CV.qword[0];
  225. temp.qword[1] ^= CV.qword[1];
  226. if (temp.byte[AES_BLOCK_SIZE - 1] > AES_BLOCK_SIZE) {
  227. ret.clear();
  228. return ret;
  229. } else {
  230. uint8_t padding = temp.byte[AES_BLOCK_SIZE - 1];
  231. for (int i = AES_BLOCK_SIZE - padding; i < AES_BLOCK_SIZE; ++i)
  232. if (temp.byte[i] != padding) {
  233. ret.clear();
  234. return ret;
  235. }
  236. for (int i = 0; i < (AES_BLOCK_SIZE - padding); ++i)
  237. ret.emplace_back(temp.byte[i]);
  238. }
  239. return ret;
  240. }
  241. };