[fix] use APIs in evp.h to encrypt and decrypt

This commit is contained in:
dijunkun
2024-11-13 00:47:54 +08:00
parent f9d024e971
commit c0154be1aa
3 changed files with 138 additions and 118 deletions

View File

@@ -279,7 +279,7 @@ class Render {
bool hostname_sent_ = false; bool hostname_sent_ = false;
bool show_confirm_delete_connection_ = false; bool show_confirm_delete_connection_ = false;
bool delete_connection_ = false; bool delete_connection_ = false;
bool remember_password_ = false; bool remember_password_ = true;
double copy_start_time_ = 0; double copy_start_time_ = 0;
double regenerate_password_start_time_ = 0; double regenerate_password_start_time_ = 0;

View File

@@ -1,7 +1,6 @@
#include "thumbnail.h" #include "thumbnail.h"
#include <openssl/aes.h> #include <openssl/evp.h>
#include <openssl/rand.h>
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
@@ -71,6 +70,29 @@ Thumbnail::~Thumbnail() {
} }
} }
void remove_colons(const char* input, char* output) {
int j = 0;
for (int i = 0; input[i] != '\0'; i++) {
if (input[i] != ':') {
output[j++] = input[i];
}
}
output[j] = '\0'; // 添加字符串结束符
}
void restore_colons(const char* input, char* output) {
int input_len = strlen(input);
int j = 0;
for (int i = 0; i < input_len; i++) {
if (i > 0 && i % 2 == 0) {
output[j++] = ':';
}
output[j++] = input[i];
}
output[j] = '\0'; // 添加字符串结束符
}
int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height, int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
const std::string& host_name, const std::string& host_name,
const std::string& remote_id, const std::string& remote_id,
@@ -85,9 +107,33 @@ int Thumbnail::SaveToThumbnail(const char* yuv420p, int width, int height,
std::string image_name = password + "@" + host_name + "@" + remote_id; std::string image_name = password + "@" + host_name + "@" + remote_id;
LOG_ERROR("1 Save thumbnail: {}", image_name); LOG_ERROR("1 Save thumbnail: {}", image_name);
std::string cipher_image_name = AES_encrypt(key_, image_name); int ciphertext_len = AES_encrypt((unsigned char*)image_name.c_str(),
LOG_ERROR("2 Save thumbnail: {}", cipher_image_name); image_name.size(), key_, iv_, ciphertext_);
std::string save_path = image_path_ + cipher_image_name;
int decryptedtext_len =
AES_decrypt(ciphertext_, ciphertext_len, key_, iv_, decryptedtext_);
decryptedtext_[decryptedtext_len] = '\0';
LOG_ERROR("ciphertext [{}]", (char*)ciphertext_);
LOG_ERROR("decryptedtext [{}]", (char*)decryptedtext_);
char* hex_str = OPENSSL_buf2hexstr(ciphertext_, ciphertext_len);
LOG_ERROR("hex [{}]", hex_str);
char* hex_str_rm = new char[256];
remove_colons(hex_str, hex_str_rm);
LOG_ERROR("hex_str_rm [{}]", hex_str_rm);
char* hex_str_re = new char[256];
restore_colons(hex_str_rm, hex_str_re);
LOG_ERROR("hex_str_re [{}]", hex_str_re);
long text_buf_len = 0;
unsigned char* text_buf = OPENSSL_hexstr2buf(hex_str, &text_buf_len);
text_buf[text_buf_len] = '\0';
LOG_ERROR("text_buf [{}]", (char*)text_buf);
std::string save_path = image_path_ + hex_str;
LOG_ERROR("Save thumbnail: {}", save_path);
stbi_write_png(save_path.data(), thumbnail_width_, thumbnail_height_, 4, stbi_write_png(save_path.data(), thumbnail_width_, thumbnail_height_, 4,
rgba_buffer_, thumbnail_width_ * 4); rgba_buffer_, thumbnail_width_ * 4);
} }
@@ -189,34 +235,36 @@ std::vector<std::filesystem::path> Thumbnail::FindThumbnailPath(
int Thumbnail::LoadThumbnail(SDL_Renderer* renderer, int Thumbnail::LoadThumbnail(SDL_Renderer* renderer,
std::map<std::string, SDL_Texture*>& textures, std::map<std::string, SDL_Texture*>& textures,
int* width, int* height) { int* width, int* height) {
textures.clear(); // textures.clear();
std::vector<std::filesystem::path> image_paths = // std::vector<std::filesystem::path> image_paths =
FindThumbnailPath(image_path_); // FindThumbnailPath(image_path_);
if (image_paths.size() == 0) { // if (image_paths.size() == 0) {
return -1; // return -1;
} else { // } else {
for (int i = 0; i < image_paths.size(); i++) { // for (int i = 0; i < image_paths.size(); i++) {
size_t pos1 = image_paths[i].string().find('/') + 1; // size_t pos1 = image_paths[i].string().find('/') + 1;
std::string cipher_image_name = image_paths[i].string().substr(pos1); // std::string cipher_image_name = image_paths[i].string().substr(pos1);
LOG_ERROR("cipher_image_name: {}", cipher_image_name); // LOG_ERROR("cipher_image_name: {}", cipher_image_name);
std::string original_image_name = AES_decrypt(key_, cipher_image_name); // std::string original_image_name = AES_decrypt(key_, cipher_image_name);
std::string image_path = image_path_ + original_image_name; // std::string image_path = image_path_ + original_image_name;
LOG_ERROR("image_path: {}", image_path); // LOG_ERROR("image_path: {}", image_path);
// size_t pos1 = original_image_name[i].string().find('@') + 1; // // size_t pos1 = original_image_name[i].string().find('@') + 1;
// size_t pos2 = original_image_name[i].string().rfind('@'); // // size_t pos2 = original_image_name[i].string().rfind('@');
// std::string password = original_image_name[i].string().substr(0, pos1); // // std::string password = original_image_name[i].string().substr(0,
// std::string host_name = // pos1);
// original_image_name[i].string().substr(pos1, pos2 - pos1); // // std::string host_name =
// std::string remote_id = original_image_name[i].string().substr(pos2 + // // original_image_name[i].string().substr(pos1, pos2 - pos1);
// 1); // // std::string remote_id = original_image_name[i].string().substr(pos2
// +
// // 1);
textures[original_image_name] = nullptr; // textures[original_image_name] = nullptr;
LoadTextureFromFile(image_path.c_str(), renderer, // LoadTextureFromFile(image_path.c_str(), renderer,
&(textures[original_image_name]), width, height); // &(textures[original_image_name]), width, height);
} // }
return 0; // return 0;
} // }
return 0; return 0;
} }
@@ -231,94 +279,61 @@ int Thumbnail::DeleteThumbnail(const std::string& file_path) {
} }
} }
// 将std::string转换为unsigned char向量 int Thumbnail::AES_encrypt(unsigned char* plaintext, int plaintext_len,
std::vector<unsigned char> string_to_uchar_vector(const std::string& str) { unsigned char* key, unsigned char* iv,
return std::vector<unsigned char>(str.begin(), str.end()); unsigned char* ciphertext_) {
} EVP_CIPHER_CTX* ctx;
int len;
// 将unsigned char向量转换为std::string int ciphertext_len;
std::string uchar_vector_to_string(const std::vector<unsigned char>& vec) { if (!(ctx = EVP_CIPHER_CTX_new())) {
return std::string(vec.begin(), vec.end()); return -1;
}
// PKCS#7 填充
void pkcs7_pad(std::vector<unsigned char>& data) {
size_t pad_length = AES_BLOCK_SIZE - (data.size() % AES_BLOCK_SIZE);
data.insert(data.end(), pad_length, static_cast<unsigned char>(pad_length));
}
// PKCS#7 去除填充
void pkcs7_unpad(std::vector<unsigned char>& data) {
if (!data.empty()) {
size_t pad_length = data.back();
data.resize(data.size() - pad_length);
} }
}
std::string Thumbnail::AES_encrypt(const std::string& key, if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
const std::string& plaintext) { return -1;
std::vector<unsigned char> key_vec = string_to_uchar_vector(key);
std::vector<unsigned char> iv(AES_BLOCK_SIZE);
RAND_bytes(iv.data(), AES_BLOCK_SIZE); // 随机生成IV
std::vector<unsigned char> plaintext_vec = string_to_uchar_vector(plaintext);
pkcs7_pad(plaintext_vec); // 填充明文
std::vector<unsigned char> ciphertext(plaintext_vec.size());
AES_KEY encryptKey;
AES_set_encrypt_key(key_vec.data(), 128, &encryptKey);
AES_cbc_encrypt(plaintext_vec.data(), ciphertext.data(), plaintext_vec.size(),
&encryptKey, iv.data(), AES_ENCRYPT);
// 将IV和密文拼接方便解密时取出IV
ciphertext.insert(ciphertext.begin(), iv.begin(), iv.end());
// return uchar_vector_to_string(ciphertext);
std::string encrypted = uchar_vector_to_string(ciphertext);
std::string original_image_name =
AES_decrypt(key_, uchar_vector_to_string(ciphertext));
LOG_ERROR("!!!!!!!!!!!!!!! src = [{}]", original_image_name);
// 转换成十六进制字符串
std::ostringstream encrypted_oss;
for (unsigned char c : encrypted) {
encrypted_oss << std::hex << std::setw(2) << std::setfill('0') << (int)c;
} }
return encrypted_oss.str();
if (1 !=
EVP_EncryptUpdate(ctx, ciphertext_, &len, plaintext, plaintext_len)) {
return -1;
}
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext_ + len, &len)) {
return -1;
}
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
} }
std::string Thumbnail::AES_decrypt(const std::string& key, int Thumbnail::AES_decrypt(unsigned char* ciphertext_, int ciphertext_len,
const std::string& ciphertext) { unsigned char* key, unsigned char* iv,
// // 将十六进制字符串转换回原始二进制密文 unsigned char* plaintext) {
std::string original_ciphertext = ciphertext; EVP_CIPHER_CTX* ctx;
// for (size_t i = 0; i < ciphertext.size(); i += 2) { int len;
// std::string byte_str = ciphertext.substr(i, 2); int plaintext_len;
// unsigned char byte = if (!(ctx = EVP_CIPHER_CTX_new())) {
// static_cast<unsigned char>(std::stoi(byte_str, nullptr, 16)); return -1;
// original_ciphertext.push_back(byte); }
// }
std::vector<unsigned char> key_vec = string_to_uchar_vector(key); if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
std::vector<unsigned char> ciphertext_vec = return -1;
string_to_uchar_vector(ciphertext); }
// 提取IV if (1 !=
std::vector<unsigned char> iv(ciphertext_vec.begin(), EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext_, ciphertext_len)) {
ciphertext_vec.begin() + AES_BLOCK_SIZE); return -1;
ciphertext_vec.erase(ciphertext_vec.begin(), }
ciphertext_vec.begin() + AES_BLOCK_SIZE);
std::vector<unsigned char> plaintext(ciphertext_vec.size()); plaintext_len = len;
AES_KEY decryptKey; if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
AES_set_decrypt_key(key_vec.data(), 128, &decryptKey); return -1;
}
AES_cbc_encrypt(ciphertext_vec.data(), plaintext.data(), plaintext_len += len;
ciphertext_vec.size(), &decryptKey, iv.data(), AES_DECRYPT); EVP_CIPHER_CTX_free(ctx);
pkcs7_unpad(plaintext); // 去除填充 return plaintext_len;
return uchar_vector_to_string(plaintext);
} }

View File

@@ -33,10 +33,13 @@ class Thumbnail {
std::vector<std::filesystem::path> FindThumbnailPath( std::vector<std::filesystem::path> FindThumbnailPath(
const std::filesystem::path& directory); const std::filesystem::path& directory);
std::string AES_encrypt(const std::string& key, const std::string& plaintext); int AES_encrypt(unsigned char* plaintext, int plaintext_len,
unsigned char* key, unsigned char* iv,
unsigned char* ciphertext);
std::string AES_decrypt(const std::string& key, int AES_decrypt(unsigned char* ciphertext, int ciphertext_len,
const std::string& ciphertext); unsigned char* key, unsigned char* iv,
unsigned char* plaintext);
private: private:
int thumbnail_width_ = 160; int thumbnail_width_ = 160;
@@ -45,8 +48,10 @@ class Thumbnail {
std::string image_path_ = "thumbnails/"; std::string image_path_ = "thumbnails/";
std::map<std::time_t, std::filesystem::path> thumbnails_sorted_by_write_time_; std::map<std::time_t, std::filesystem::path> thumbnails_sorted_by_write_time_;
std::string key_ = "1234567890123456"; unsigned char* key_ = (unsigned char*)"01234567890123456789012345678901";
std::string iv_ = "1234567890123456"; unsigned char* iv_ = (unsigned char*)"01234567890123456";
unsigned char ciphertext_[64];
unsigned char decryptedtext_[64];
}; };
#endif #endif