From bf68cfc532232e652ef0645d0cdd834b02d52f81 Mon Sep 17 00:00:00 2001 From: kradchen Date: Fri, 7 Mar 2025 09:19:45 +0800 Subject: [PATCH] feat: add encrypt class(AESEncryptHelper) and CMake link logic --- CMakeLists.txt | 4 +- src/utilities/AESEncryptHelper.cpp | 119 +++++++++++++++++++++++++++++ src/utilities/AESEncryptHelper.h | 14 ++++ 3 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/utilities/AESEncryptHelper.cpp create mode 100644 src/utilities/AESEncryptHelper.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b71a69..a77d782 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ endif() find_package(Qt5 COMPONENTS Core Widgets Gui Sql Network Multimedia MultimediaWidgets WebEngineWidgets REQUIRED) find_package(DCMTK REQUIRED) - +find_package(OpenSSL REQUIRED) include_directories(${DCMTK_INCLUDE_DIRS}) @@ -80,7 +80,7 @@ add_executable(${PROJECT_NAME} ${project_headers} ${project_cpps} ${project_cxx} if(${DCMTK_FOUND}) target_link_libraries(${PROJECT_NAME} dcmnet) endif() - +target_link_libraries(${PROJECT_NAME} PUBLIC ${OPENSSL_LIBRARIES}) target_compile_definitions(${PROJECT_NAME} PRIVATE # If the debug configuration pass the DEBUG define to the compiler diff --git a/src/utilities/AESEncryptHelper.cpp b/src/utilities/AESEncryptHelper.cpp new file mode 100644 index 0000000..8faa7ff --- /dev/null +++ b/src/utilities/AESEncryptHelper.cpp @@ -0,0 +1,119 @@ +#include "AESEncryptHelper.h" + +#include +#include +#include +#include + +#include +#include + +// 错误处理宏 +#define HANDLE_ERROR(cond, msg) \ + if (cond) { \ + std::cerr << "Error: " << msg << std::endl; \ + return std::string(); \ + } + +namespace +{ + const unsigned char ENCRYPT_KEY[] = {0x00, 0xa1, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; + const unsigned char ENCRYPT_IV[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; + + std::string base64_encode(const std::vector& data) { + BIO *bio, *b64; + BUF_MEM *bufferPtr; + + // 创建一个 Base64 编码的 BIO + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new(BIO_s_mem()); + bio = BIO_push(b64, bio); + + // 设置不换行 + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); + + // 写入数据 + BIO_write(bio, data.data(), data.size()); + BIO_flush(bio); + + // 获取编码后的字符串 + BUF_MEM *bptr; + BIO_get_mem_ptr(bio, &bptr); + BIO_set_close(bio, BIO_NOCLOSE); + + // 创建字符串 + std::string base64_str(bptr->data, bptr->length); + + // 释放资源 + BIO_free_all(bio); + + return base64_str; +} + +std::string base64_decode(const std::string& aInput) { + BIO* b64 = BIO_new(BIO_f_base64()); + BIO* bio = BIO_new_mem_buf(aInput.c_str(), -1); + bio = BIO_push(b64, bio); + + BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // 去掉换行符 + + size_t decode_len = (aInput.size() / 4) * 3; + if (aInput[aInput.size() - 1] == '=') decode_len--; + if (aInput[aInput.size() - 2] == '=') decode_len--; + + std::string decoded; + decoded.resize(decode_len); + + int len = BIO_read(bio, &decoded[0], aInput.size()); + decoded.resize(len); + + BIO_free_all(bio); + + return decoded; +} + +} + + +std::string AESEncryptHelper::encrypt(const std::string &aPlainText){ + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + HANDLE_ERROR(ctx == nullptr, "EVP_CIPHER_CTX_new failed"); + + // Initialize encryption + HANDLE_ERROR(EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), nullptr, ENCRYPT_KEY, ENCRYPT_IV) != 1, "EVP_EncryptInit_ex failed"); + + std::vector ciphertext(aPlainText.size() + EVP_CIPHER_block_size(EVP_aes_128_cbc())); + int len; + HANDLE_ERROR(EVP_EncryptUpdate(ctx, ciphertext.data(), &len, reinterpret_cast(aPlainText.data()), aPlainText.size()) != 1, "EVP_EncryptUpdate failed"); + int ciphertext_len = len; + + HANDLE_ERROR(EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) != 1, "EVP_EncryptFinal_ex failed"); + ciphertext_len += len; + + ciphertext.resize(ciphertext_len); + EVP_CIPHER_CTX_free(ctx); + return ::base64_encode(ciphertext); +} + +std::string AESEncryptHelper::decrypt(const std::string &aCipherText) +{ + std::string unbase = base64_decode(aCipherText); + + EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); + HANDLE_ERROR(ctx == nullptr, "EVP_CIPHER_CTX_new failed"); + + // Initialize decryption + HANDLE_ERROR(EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), nullptr, ENCRYPT_KEY, ENCRYPT_IV) != 1, "EVP_DecryptInit_ex failed"); + + std::vector plaintext(unbase.size()); + int len; + HANDLE_ERROR(EVP_DecryptUpdate(ctx, plaintext.data(), &len, reinterpret_cast(unbase.data()), unbase.size()) != 1, "EVP_DecryptUpdate failed"); + int plaintext_len = len; + + HANDLE_ERROR(EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) != 1, "EVP_DecryptFinal_ex failed"); + plaintext_len += len; + + EVP_CIPHER_CTX_free(ctx); + return std::string(reinterpret_cast(plaintext.data()), plaintext_len); +} + diff --git a/src/utilities/AESEncryptHelper.h b/src/utilities/AESEncryptHelper.h new file mode 100644 index 0000000..a50afd6 --- /dev/null +++ b/src/utilities/AESEncryptHelper.h @@ -0,0 +1,14 @@ +#ifndef AESENCRYPTHELPER_H +#define AESENCRYPTHELPER_H + +#include +class AESEncryptHelper +{ +public: + AESEncryptHelper() = delete; + + static std::string encrypt(const std::string& aPlainText); + static std::string decrypt(const std::string& aCipherText); +}; + +#endif /* ALAESENCRYPTHELPER_H */