aes_utils.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //
  2. // Created by #Suyghur, on 2021/06/11.
  3. //
  4. #include <hex_utils.h>
  5. #include <logger.h>
  6. #include <toolkit.h>
  7. #include "include/aes/aes_utils.h"
  8. static const unsigned char HEX[16] = {0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
  9. 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
  10. static const unsigned char CHAR_SET[36] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
  11. 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  12. 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  13. 'u', 'v', 'w', 'x', 'y', 'z'};
  14. uint8_t *AesUtils::GetPaddingInput(const char *input) {
  15. // 输入的长度
  16. int input_len = (int) strlen(input);
  17. int remainder = input_len % BLOCKLEN;
  18. uint8_t *padding_input = nullptr;
  19. int group = input_len / BLOCKLEN;
  20. auto size = (size_t) (BLOCKLEN * (group + 1));
  21. padding_input = (uint8_t *) malloc(size + 1);
  22. int dif = (int) size - input_len;
  23. for (int i = 0; i < size; i++) {
  24. if (i < input_len) {
  25. padding_input[i] = (uint8_t) input[i];
  26. } else {
  27. if (remainder == 0) {
  28. // 刚好是16倍数, 就填充16个16 (0x10)
  29. padding_input[i] = HEX[0];
  30. } else {
  31. // 如果不足16位 少多少位就补几个几
  32. padding_input[i] = HEX[dif];
  33. }
  34. }
  35. }
  36. padding_input[size] = '\0';
  37. return padding_input;
  38. }
  39. int AesUtils::FindPaddingIndex(uint8_t *str, size_t length) {
  40. int i, k;
  41. for (i = 0; i < length; i++) {
  42. char c = str[i];
  43. if ('\0' != c) {
  44. for (k = 0; k < 16; ++k) {
  45. if (HEX[k] == c) {
  46. return i;
  47. }
  48. }
  49. }
  50. }
  51. return i;
  52. }
  53. void AesUtils::RemovePadding(uint8_t *out, size_t length) {
  54. int index = FindPaddingIndex(out, length);
  55. if (index < length) {
  56. memset(out + index, '\0', length - index);
  57. }
  58. }
  59. char *AesUtils::GetRawKey() {
  60. const int len = 26;
  61. time_t ts = time(nullptr);
  62. srandom(ts);
  63. auto *raw_key = static_cast<char *>(malloc(len + 1));
  64. memset(raw_key, 0, len + 1);
  65. for (int i = 0; i < 16; ++i) {
  66. raw_key[i] = CHAR_SET[random() % 36];
  67. }
  68. sprintf(raw_key, "%s%ld", raw_key, ts);
  69. raw_key[len] = '\0';
  70. return raw_key;
  71. }
  72. uint8_t *AesUtils::GetKey() {
  73. const int len = 16;
  74. auto *key = static_cast<uint8_t *>(malloc(len + 1));
  75. for (int i = 0; i < len; ++i) {
  76. key[i] = CHAR_SET[random() % 36];
  77. }
  78. key[len] = '\0';
  79. return key;
  80. }
  81. uint8_t *AesUtils::GetIv(const uint8_t *key) {
  82. const int len = 16;
  83. auto *iv = static_cast<uint8_t *>(malloc(len + 1));
  84. for (int i = 0; i < len; i++) {
  85. iv[i] = key[len - (i + 1)];
  86. }
  87. iv[len] = '\0';
  88. return iv;
  89. }
  90. char *AesUtils::GetIv32(const char *key) {
  91. const int len = 32;
  92. auto *iv = static_cast<char *>(malloc(len + 1));
  93. for (int i = 0; i < len; i++) {
  94. iv[i] = key[len - (i + 1)];
  95. }
  96. iv[len] = '\0';
  97. return iv;
  98. }
  99. /**
  100. * AES加密, CBC, PKCS5Padding
  101. */
  102. char *AesUtils::Encrypt(const char *input, const uint8_t *key) {
  103. // const uint8_t *key = GetKey();
  104. const uint8_t *iv = GetIv(key);
  105. uint8_t *padding_input = GetPaddingInput(input);
  106. size_t padding_input_length = strlen((char *) padding_input);
  107. auto *out = (unsigned char *) malloc(padding_input_length);
  108. AES_CBC_encrypt_buffer(out, padding_input, (uint32_t) padding_input_length, key, iv);
  109. char *hex_raw = HexUtils::HexEncode(out, padding_input_length);
  110. free(padding_input);
  111. free(out);
  112. // free((void *) key);
  113. free((void *) iv);
  114. return hex_raw;
  115. }
  116. /**
  117. * AES解密, CBC, PKCS5Padding
  118. */
  119. char *AesUtils::Decrypt(const char *input, const uint8_t *key) {
  120. const uint8_t *iv = GetIv(key);
  121. // const uint8_t *iv = reinterpret_cast<const uint8_t *>(ToolKit::StrReverse(reinterpret_cast<const char *>(key)));
  122. size_t len = strlen(input);
  123. unsigned char *input_des = HexUtils::HexDecode(input);
  124. const size_t input_length = (len / 4) * 3 / BLOCKLEN * BLOCKLEN;
  125. auto *src = static_cast<uint8_t *>(malloc(input_length));
  126. memset(src, 0, input_length);
  127. AES_CBC_decrypt_buffer(src, input_des, (uint32_t) input_length, key, iv);
  128. RemovePadding(src, input_length);
  129. free(input_des);
  130. // free((void *) key);
  131. free((void *) iv);
  132. return (char *) src;
  133. }
  134. std::string AesUtils::Decrypt2(JNIEnv *env, const std::string &key, const std::string &enc) {
  135. jclass clz = env->FindClass("cn/yyxx/support/encryption/aes/AesUtils");
  136. if (clz == nullptr) {
  137. LOGE("aes impl clz is nullptr !!!");
  138. return "";
  139. }
  140. const char *method_name = "decrypt";
  141. const char *sig = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
  142. jmethodID jmethod_id = env->GetStaticMethodID(clz, method_name, sig);
  143. jstring jkey = env->NewStringUTF(key.c_str());
  144. jstring jraw = env->NewStringUTF(enc.c_str());
  145. jstring jresult = (jstring) env->CallStaticObjectMethod(clz, jmethod_id, jkey, jraw);
  146. return ToolKit::JString2String(env, jresult);
  147. }
  148. std::string AesUtils::Encrypt2(JNIEnv *env, const std::string &key, const std::string &raw) {
  149. jclass clz = env->FindClass("cn/yyxx/support/encryption/aes/AesUtils");
  150. if (clz == nullptr) {
  151. LOGE("aes impl clz is nullptr !!!");
  152. return "";
  153. }
  154. const char *method_name = "encrypt";
  155. const char *sig = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
  156. jmethodID jmethod_id = env->GetStaticMethodID(clz, method_name, sig);
  157. jstring jkey = env->NewStringUTF(key.c_str());
  158. jstring jraw = env->NewStringUTF(raw.c_str());
  159. jstring jresult = (jstring) env->CallStaticObjectMethod(clz, jmethod_id, jkey, jraw);
  160. return ToolKit::JString2String(env, jresult);
  161. }