From 4a5d5756875156f170522d472580a14b9b467841 Mon Sep 17 00:00:00 2001 From: Lenheart <947330670@qq.com> Date: Thu, 21 Apr 2022 13:06:03 +0800 Subject: [PATCH] 111 --- test/BASE64.cpp | 234 ++++++++++++++++++++++++++++++++++++++ test/BASE64.h | 40 +++++++ test/framework.h | 2 +- test/test.vcxproj | 2 + test/test.vcxproj.filters | 6 + 5 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 test/BASE64.cpp create mode 100644 test/BASE64.h diff --git a/test/BASE64.cpp b/test/BASE64.cpp new file mode 100644 index 0000000..11caee1 --- /dev/null +++ b/test/BASE64.cpp @@ -0,0 +1,234 @@ + +#include "pch.h" +#include "BASE64.h" +#include +#include +#include + + +using namespace LenheartBase; + +// 编解码转换表 +unsigned char CBASE64::s_encTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +unsigned char CBASE64::s_decTable[] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xFF,0xFF,0x3F, + 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, + 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF +}; + +// 执行BASE64编码操作 +std::string CBASE64::encode(const std::string& str) +{ + std::string strEncode; + strEncode.resize((str.size() / 3 + 1) * 4); + strEncode.resize(__encode((unsigned char*)strEncode.data(), (const unsigned char*)str.data(), str.size())); + return strEncode; +} + +// 执行BASE64解码操作 +std::string CBASE64::decode(const std::string& str) +{ + std::string strDecode; + strDecode.resize(str.size()); + strDecode.resize(__decode((unsigned char*)strDecode.data(), (const unsigned char*)str.data(), str.size())); + return strDecode; +} + +// 分组编码 +int CBASE64::__encode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen) +{ + unsigned char* dst = pDest; + const unsigned char* src = pSrc; + size_t len = nSrcLen; + + unsigned char* odst = dst; + unsigned long l = 0, m = 0, n = 0; + + // 循环处理分组 + size_t off = 0; + for (; off + 3 <= len; off += 3) + { + l = *src++; + m = *src++; + n = *src++; + + *dst++ = s_encTable[(l >> 2) & 0x3F]; + *dst++ = s_encTable[((l << 4) & 0x30) | ((m >> 4) & 0x0F)]; + *dst++ = s_encTable[((m << 2) & 0x3C) | ((n >> 6) & 0x03)]; + *dst++ = s_encTable[n & 0x3F]; + } + + // 处理余下的2个字节 + if (off + 2 <= len) + { + l = *src++; + m = *src++; + + *dst++ = s_encTable[(l >> 2) & 0x3F]; + *dst++ = s_encTable[((l << 4) & 0x30) | ((m >> 4) & 0x0F)]; + *dst++ = s_encTable[((m << 2) & 0x3C)]; + *dst++ = '='; + } + + // 处理余下的1个字节 + else if (off + 1 <= len) + { + l = *src++; + + *dst++ = s_encTable[(l >> 2) & 0x3F]; + *dst++ = s_encTable[((l << 4) & 0x30)]; + *dst++ = '='; + *dst++ = '='; + } + + return (int)(dst - odst); +} + +// 分组解码 +int CBASE64::__decode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen) +{ + unsigned char* dst = pDest; + const unsigned char* src = pSrc; + size_t len = nSrcLen; + + unsigned char* odst = dst; + unsigned long l = 0, m = 0, n = 0, o = 0; + + // 循环处理分组 + size_t off = 0; + for (; off + 4 <= len; off += 4) + { + if ((src[0] > 0x7F) || (src[1] > 0x7F) || (src[2] > 0x7F) || (src[3] > 0x7F)) return (int)(dst - odst); + if ((src[0] == '=') || (src[1] == '=') || (src[2] == '=') || (src[3] == '=')) break; + + l = s_decTable[*src++]; + m = s_decTable[*src++]; + n = s_decTable[*src++]; + o = s_decTable[*src++]; + + *dst++ = (unsigned char)(((l << 2) & 0xFC) | ((m >> 4) & 0x03)); + *dst++ = (unsigned char)(((m << 4) & 0xF0) | ((n >> 2) & 0x0F)); + *dst++ = (unsigned char)(((n << 6) & 0xC0) | (o & 0x3F)); + } + + // 处理余下的3个字节 + if (off + 3 <= len) + { + if ((src[0] != '=') && (src[1] != '=')) + { + l = s_decTable[*src++]; + m = s_decTable[*src++]; + + *dst++ = (unsigned char)(((l << 2) & 0xFC) | ((m >> 4) & 0x03)); + } + + if ((src[2] != '=')) + { + n = s_decTable[*src++]; + + *dst++ = (unsigned char)(((m << 4) & 0xF0) | ((n >> 2) & 0x0F)); + } + } + + // 处理余下的两个字节 + else if (off + 2 <= len) + { + if ((src[0] != '=') && (src[1] != '=')) + { + l = s_decTable[*src++]; + m = s_decTable[*src++]; + + *dst++ = (unsigned char)(((l << 2) & 0xFC) | ((m >> 4) & 0x03)); + } + } + + return (int)(dst - odst); +} + + +std::string CBASE64::RsaPriDecrypt(const std::string& cipher_text, const std::string& pri_key) +{ + std::string decrypt_text; + RSA* rsa = RSA_new(); + BIO* keybio; + keybio = BIO_new_mem_buf((unsigned char*)pri_key.c_str(), -1); + + rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); + if (rsa == nullptr) { + unsigned long err = ERR_get_error(); //获取错误号 + char err_msg[1024] = { 0 }; + ERR_error_string(err, err_msg); // 格式:error:errId:库:函数:原因 + return std::string(); + } + + // 获取RSA单次处理的最大长度 + int key_len = RSA_size(rsa); + char* sub_text = new char[key_len + 1]; + memset(sub_text, 0, key_len + 1); + int ret = 0; + std::string sub_str; + unsigned int pos = 0; + // 对密文进行分段解密 + while (pos < cipher_text.length() - 1) { + sub_str = cipher_text.substr(pos, key_len); + memset(sub_text, 0, key_len + 1); + ret = RSA_private_decrypt(sub_str.length(), (const unsigned char*)sub_str.c_str(), (unsigned char*)sub_text, rsa, 1); + if (ret >= 0) { + decrypt_text.append(std::string(sub_text, ret)); + //printf("pos:%d, Length: %d ,sub: %s\n", pos, cipher_text.length(),sub_text); + pos += key_len; + } + } + // 释放内存 + delete[] sub_text; + BIO_free_all(keybio); + RSA_free(rsa); + + return decrypt_text; +} + +std::string CBASE64::RsaPriEncrypt(const std::string& clear_text, const std::string& pri_key) +{ + std::string encrypt_text; + BIO* keybio = BIO_new_mem_buf((unsigned char*)pri_key.c_str(), -1); + RSA* rsa = RSA_new(); + rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL); + if (!rsa) + { + BIO_free_all(keybio); + return std::string(""); + } + + // 获取RSA单次可以处理的数据块的最大长度 + int key_len = RSA_size(rsa); + int block_len = key_len - 11; // 因为填充方式为RSA_PKCS1_PADDING, 所以要在key_len基础上减去11 + + // 申请内存:存贮加密后的密文数据 + char* sub_text = new char[key_len + 1]; + memset(sub_text, 0, key_len + 1); + int ret = 0; + unsigned int pos = 0; + std::string sub_str; + // 对数据进行分段加密(返回值是加密后数据的长度) + while (pos < clear_text.length()) { + sub_str = clear_text.substr(pos, block_len); + memset(sub_text, 0, key_len + 1); + ret = RSA_private_encrypt(sub_str.length(), (const unsigned char*)sub_str.c_str(), (unsigned char*)sub_text, rsa, RSA_PKCS1_PADDING); + if (ret >= 0) { + encrypt_text.append(std::string(sub_text, ret)); + } + pos += block_len; + } + + // 释放内存 + delete sub_text; + BIO_free_all(keybio); + RSA_free(rsa); + + return encrypt_text; +} diff --git a/test/BASE64.h b/test/BASE64.h new file mode 100644 index 0000000..bc2adea --- /dev/null +++ b/test/BASE64.h @@ -0,0 +1,40 @@ +#ifndef __DAKUANG_BASE64_H__ +#define __DAKUANG_BASE64_H__ + +#include + +namespace LenheartBase +{ + + class CBASE64 + { + public: + + // 执行BASE64编码操作 + static std::string encode(const std::string& str); + + // 执行BASE64解码操作 + static std::string decode(const std::string& str); + + // 执行RSA私匙解密操作 + static std::string RsaPriDecrypt(const std::string& cipher_text, const std::string& pri_key); + // 执行RSA私匙加密操作 + static std::string RsaPriEncrypt(const std::string& clear_text, const std::string& pri_key); + private: + + // 分组编码 + static int __encode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen); + + // 分组解码 + static int __decode(unsigned char* pDest, const unsigned char* pSrc, size_t nSrcLen); + + private: + + // 编解码转换表 + static unsigned char s_encTable[]; + static unsigned char s_decTable[]; + }; + +} + +#endif \ No newline at end of file diff --git a/test/framework.h b/test/framework.h index 6237e6e..ceadb28 100644 --- a/test/framework.h +++ b/test/framework.h @@ -55,11 +55,11 @@ #if defined LOCALHOSTS_SWITCH #else +#define CPPHTTPLIB_OPENSSL_SUPPORT #include "framework.h" #include "RSAC.h" #include "BASE64.h" #include "httplib.h" -#define CPPHTTPLIB_OPENSSL_SUPPORT #endif diff --git a/test/test.vcxproj b/test/test.vcxproj index fc1dad2..373eb1e 100644 --- a/test/test.vcxproj +++ b/test/test.vcxproj @@ -172,6 +172,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/test/test.vcxproj.filters b/test/test.vcxproj.filters index b260c0b..868a34b 100644 --- a/test/test.vcxproj.filters +++ b/test/test.vcxproj.filters @@ -45,6 +45,9 @@ 澶存枃浠 + + 澶存枃浠 + @@ -74,5 +77,8 @@ 婧愭枃浠 + + 婧愭枃浠 + \ No newline at end of file