235 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
		
		
			
		
	
	
			235 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C++
		
	
	
	
|  | 
 | |||
|  | #include "pch.h"
 | |||
|  | #include "BASE64.h"
 | |||
|  | #include <openssl/rsa.h>
 | |||
|  | #include <openssl/pem.h>
 | |||
|  | #include <openssl/err.h>
 | |||
|  | 
 | |||
|  | 
 | |||
|  | using namespace LenheartBase; | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
 | |||
|  | 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 | |||
|  | }; | |||
|  | 
 | |||
|  | // ִ<><D6B4>BASE64<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | 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; | |||
|  | } | |||
|  | 
 | |||
|  | // ִ<><D6B4>BASE64<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | 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; | |||
|  | } | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | 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; | |||
|  | 
 | |||
|  |     // ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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]; | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>2<EFBFBD><32><EFBFBD>ֽ<EFBFBD>
 | |||
|  |     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++ = '='; | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>1<EFBFBD><31><EFBFBD>ֽ<EFBFBD>
 | |||
|  |     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); | |||
|  | } | |||
|  | 
 | |||
|  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  | 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; | |||
|  | 
 | |||
|  |     // ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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)); | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>3<EFBFBD><33><EFBFBD>ֽ<EFBFBD>
 | |||
|  |     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)); | |||
|  |         } | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
 | |||
|  |     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(); //<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |         char err_msg[1024] = { 0 }; | |||
|  |         ERR_error_string(err, err_msg); // <20><>ʽ<EFBFBD><CABD>error:errId:<3A><>:<3A><><EFBFBD><EFBFBD>:ԭ<><D4AD>
 | |||
|  |         return std::string(); | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><>ȡRSA<53><41><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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; | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD>зֶν<D6B6><CEBD><EFBFBD>
 | |||
|  |     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; | |||
|  |         } | |||
|  |     } | |||
|  |     // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>  
 | |||
|  |     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(""); | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20><>ȡRSA<53><41><EFBFBD>ο<EFBFBD><CEBF>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݿ<EFBFBD><DDBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     int key_len = RSA_size(rsa); | |||
|  |     int block_len = key_len - 11;    // <20><>Ϊ<EFBFBD><CEAA><EFBFBD>䷽ʽΪRSA_PKCS1_PADDING, <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>key_len<65><6E><EFBFBD><EFBFBD><EFBFBD>ϼ<EFBFBD>ȥ11
 | |||
|  | 
 | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD>ڴ棺<DAB4><E6A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | |||
|  |     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; | |||
|  |     // <20><><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>зֶμ<D6B6><CEBC>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>Ǽ<EFBFBD><C7BC>ܺ<EFBFBD><DCBA><EFBFBD><EFBFBD>ݵij<DDB5><C4B3>ȣ<EFBFBD>
 | |||
|  |     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; | |||
|  |     } | |||
|  | 
 | |||
|  |     // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>  
 | |||
|  |     delete sub_text; | |||
|  |     BIO_free_all(keybio); | |||
|  |     RSA_free(rsa); | |||
|  | 
 | |||
|  |     return encrypt_text; | |||
|  | } |