From df21719faf4fbd4580640dfc7dfdee3fe8a1680c Mon Sep 17 00:00:00 2001 From: taynpg Date: Wed, 28 Feb 2024 17:02:36 +0800 Subject: [PATCH] =?UTF-8?q?RSA=E5=8A=A0=E5=AF=86=E8=A7=A3=E5=AF=86?= =?UTF-8?q?=E5=BA=93=E8=B0=83=E8=AF=95=E9=80=9A=E8=BF=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 3 ++- cryp/CMakeLists.txt | 3 ++- cryp/box_rsa.cpp | 35 ++++++++++++++++++-------- cryp/box_rsa.h | 17 +++++++------ test/CMakeLists.txt | 5 ++++ test/cryp_test/CMakeLists.txt | 6 +++++ test/cryp_test/main.cpp | 47 +++++++++++++++++++++++++++++++++++ 7 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 test/CMakeLists.txt create mode 100644 test/cryp_test/CMakeLists.txt create mode 100644 test/cryp_test/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 579f2aa..a2efd7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,4 +11,5 @@ if (MSVC) add_compile_options(-D_CRT_SECURE_NO_WARNINGS) endif() -add_subdirectory(cryp) \ No newline at end of file +add_subdirectory(cryp) +add_subdirectory(test) \ No newline at end of file diff --git a/cryp/CMakeLists.txt b/cryp/CMakeLists.txt index 9d29e51..9eb443f 100644 --- a/cryp/CMakeLists.txt +++ b/cryp/CMakeLists.txt @@ -4,4 +4,5 @@ set(CMAKE_CXX_STANDARD 11) find_package(OpenSSL REQUIRED) add_library(box_cryp STATIC "box_rsa.h" "box_rsa.cpp") -target_link_libraries(box_cryp PRIVATE OpenSSL::SSL OpenSSL::Crypto) \ No newline at end of file +target_link_libraries(box_cryp PRIVATE OpenSSL::SSL OpenSSL::Crypto) +target_include_directories(box_cryp PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) \ No newline at end of file diff --git a/cryp/box_rsa.cpp b/cryp/box_rsa.cpp index 7c28f47..c44bf9f 100644 --- a/cryp/box_rsa.cpp +++ b/cryp/box_rsa.cpp @@ -7,7 +7,6 @@ #include #include - constexpr size_t g_buffsize = 2048; namespace cppbox { @@ -17,8 +16,8 @@ class CRSAOperatorImp public: CRSAOperatorImp() { - err_ = new char[g_buffsize]; - ioerr_ = BIO_new_mem_buf(err_, g_buffsize); + err_ = new char[g_buffsize + 1]; + ioerr_ = BIO_new(BIO_s_mem()); } ~CRSAOperatorImp() { @@ -32,7 +31,7 @@ public: mem_ = BIO_new_mem_buf((void*)public_pem.data, public_pem.len); key_ = PEM_read_bio_PUBKEY(mem_, nullptr, nullptr, nullptr); if (key_ == nullptr) { - std::snprintf(err_, g_buffsize, "Read From Public Key Mem Data Failed."); + ERR_print_errors(ioerr_); clear(); return false; } @@ -47,6 +46,7 @@ public: if (EVP_PKEY_encrypt(ctx_, result.data, &result.len, data.data, data.len) <= 0) { free_data(result); clear(); + ERR_print_errors(ioerr_); return false; } clear(); @@ -58,7 +58,7 @@ public: mem_ = BIO_new_mem_buf((void*)private_pem.data, private_pem.len); key_ = PEM_read_bio_PrivateKey(mem_, nullptr, nullptr, nullptr); if (key_ == nullptr) { - std::snprintf(err_, g_buffsize, "Read From Private Key Mem Data Failed."); + ERR_print_errors(ioerr_); clear(); return false; } @@ -76,6 +76,7 @@ public: ERR_print_errors(ioerr_); return false; } + result.data[result.len] = '\0'; clear(); return true; } @@ -93,13 +94,14 @@ public: file_data.len = ftell(fp); fseek(fp, 0, SEEK_SET); - file_data.data = (unsigned char*)malloc(file_data.len); + alloc_data(file_data); if (file_data.data == NULL) { fclose(fp); std::snprintf(err_, g_buffsize, "Alloc Mem Failed: %zd", file_data.len); return false; } file_data.len = fread(file_data.data, 1, file_data.len, fp); + fclose(fp); bool ret = encrypt_pub(file_data, data, result); free(file_data.data); return ret; @@ -118,13 +120,14 @@ public: file_data.len = ftell(fp); fseek(fp, 0, SEEK_SET); - file_data.data = (unsigned char*)malloc(file_data.len); + alloc_data(file_data); if (file_data.data == NULL) { fclose(fp); std::snprintf(err_, g_buffsize, "Alloc Mem Failed: %zd", file_data.len); return false; } file_data.len = fread(file_data.data, 1, file_data.len, fp); + fclose(fp); bool ret = decrypt_pri(file_data, data, result); free(file_data.data); return ret; @@ -145,12 +148,16 @@ public: } key_ = EVP_RSA_gen(g_buffsize / 2); if (key_ == nullptr) { - ERR_print_errors_fp(stderr); + ERR_print_errors(ioerr_); return false; } PEM_write_PUBKEY(fp_pub, key_); PEM_write_PrivateKey(fp_pri, key_, nullptr, nullptr, 0, nullptr, nullptr); clear(); + + fclose(fp_pub); + fclose(fp_pri); + return true; } @@ -199,12 +206,14 @@ public: data.data = nullptr; return; } - data.data = static_cast(malloc(data.len)); + data.data = static_cast(malloc(data.len + 1)); } void get_last_error(char* buf, int len) { - std::snprintf(buf, len, err_, strlen(err_)); + int read_len = BIO_read(ioerr_, err_, g_buffsize); + std::snprintf(buf, len, err_, read_len); + buf[read_len] = '\0'; } private: @@ -275,4 +284,10 @@ const char* CRSAOperator::get_last_error() const return err_; } +void CRSAOperator::free_hdata(HData& data) +{ + assert(imp_); + imp_->free_data(data); +} + } // namespace cppbox \ No newline at end of file diff --git a/cryp/box_rsa.h b/cryp/box_rsa.h index 627c165..69f205a 100644 --- a/cryp/box_rsa.h +++ b/cryp/box_rsa.h @@ -5,7 +5,7 @@ namespace cppbox { struct HData { unsigned char* data; - size_t len; + size_t len; }; class CRSAOperatorImp; @@ -14,16 +14,19 @@ class CRSAOperator private: CRSAOperatorImp* imp_{}; char* err_{}; + public: CRSAOperator(); ~CRSAOperator(); + public: - bool encrypt_pub(const HData& public_pem, const HData& data, HData& result); - bool encrypt_pub(const char* pub_path, const HData& data, HData& result); - bool decrypt_pri(const HData& private_pem, const HData& data, HData& result); - bool decrypt_pri(const char* pri_path, const HData& data, HData& result); - bool generate_keypair(const char* pub_path, const char* pri_path); - bool generate_keypair(HData& pub, HData& pri); + bool encrypt_pub(const HData& public_pem, const HData& data, HData& result); + bool encrypt_pub(const char* pub_path, const HData& data, HData& result); + bool decrypt_pri(const HData& private_pem, const HData& data, HData& result); + bool decrypt_pri(const char* pri_path, const HData& data, HData& result); + bool generate_keypair(const char* pub_path, const char* pri_path); + bool generate_keypair(HData& pub, HData& pri); + void free_hdata(HData& data); const char* get_last_error() const; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..869ee40 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 3.8) +project (auxiliarytool_test) +set(CMAKE_CXX_STANDARD 11) + +add_subdirectory(cryp_test) \ No newline at end of file diff --git a/test/cryp_test/CMakeLists.txt b/test/cryp_test/CMakeLists.txt new file mode 100644 index 0000000..272ba31 --- /dev/null +++ b/test/cryp_test/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required (VERSION 3.8) +project (cryp_test) +set(CMAKE_CXX_STANDARD 11) + +add_executable(cryp_test "main.cpp") +target_link_libraries(cryp_test PRIVATE box_cryp) \ No newline at end of file diff --git a/test/cryp_test/main.cpp b/test/cryp_test/main.cpp new file mode 100644 index 0000000..f95fbee --- /dev/null +++ b/test/cryp_test/main.cpp @@ -0,0 +1,47 @@ +#include +#include +#include + +using namespace cppbox; + +CRSAOperator opr; + +void file_test() +{ + if (!opr.generate_keypair("public.pem", "private.pem")) { + std::cout << opr.get_last_error() << std::endl; + } + + const char* pub = "public.pem"; + const char* pri = "private.pem"; + + HData source_data; + int size = 512; + source_data.data = (unsigned char*)malloc(size); + source_data.len = size; + source_data.len = std::snprintf((char *)source_data.data, source_data.len, "This is a cryp test!"); + + HData en_result_data; + HData de_result_data; + if (!opr.encrypt_pub(pub, source_data, en_result_data)) { + std::cout << opr.get_last_error() << std::endl; + } + if (!opr.decrypt_pri(pri, en_result_data, de_result_data)) { + std::cout << opr.get_last_error() << std::endl; + } + assert(strcmp((const char *)de_result_data.data, (const char *)source_data.data) == 0); + + opr.free_hdata(en_result_data); + opr.free_hdata(de_result_data); + remove(pub); + remove(pri); + + std::cout << "cryp_test success!" << std::endl; +} + +int main() +{ + file_test(); + + return 0; +} \ No newline at end of file