| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | #include "pch.h"
 | 
					
						
							|  |  |  |  | #include "BASE64.h"
 | 
					
						
							|  |  |  |  | #include <openssl/rsa.h>
 | 
					
						
							|  |  |  |  | #include <openssl/pem.h>
 | 
					
						
							|  |  |  |  | #include <openssl/err.h>
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | using namespace LenheartBase; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // <20>ӽ<EFBFBD><D3BD>ܺ<EFBFBD><DCBA><EFBFBD>ǩ<EFBFBD><C7A9>
 | 
					
						
							|  |  |  |  | typedef int (*RSA_encryptOrDecrypt)(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, int padding); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | unsigned char CBASE64::s_encTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 
					
						
							|  |  |  |  | unsigned char CBASE64::s_decTable[] = { | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     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 }; | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // ִ<><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) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |         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; | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |         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); | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     if (rsa == nullptr) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |         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>
 | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     while (pos < cipher_text.length() - 1) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |         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); | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |         if (ret >= 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |             decrypt_text.append(std::string(sub_text, ret)); | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |             // printf("pos:%d, Length: %d ,sub: %s\n", pos, cipher_text.length(),sub_text);
 | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |             pos += key_len; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |     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); | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     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
 | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <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>
 | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     while (pos < clear_text.length()) | 
					
						
							|  |  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |         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); | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |         if (ret >= 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |             encrypt_text.append(std::string(sub_text, ret)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         pos += block_len; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  |     // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
 | 
					
						
							| 
									
										
										
										
											2022-04-21 13:06:03 +08:00
										 |  |  |  |     delete sub_text; | 
					
						
							|  |  |  |  |     BIO_free_all(keybio); | 
					
						
							|  |  |  |  |     RSA_free(rsa); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return encrypt_text; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-04-14 14:56:01 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // <20><><EFBFBD><EFBFBD>RSA<53><41>Կ<EFBFBD>ṹ
 | 
					
						
							|  |  |  |  | void* CBASE64::__genKey(int nBits) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     RSA* rsa = RSA_new(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     BIGNUM* bne = BN_new(); | 
					
						
							|  |  |  |  |     BN_set_word(bne, RSA_F4); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     int ret = RSA_generate_key_ex(rsa, nBits, bne, NULL); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     BN_free(bne); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (ret != 1) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         RSA_free(rsa); | 
					
						
							|  |  |  |  |         return NULL; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return (void*)rsa; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ<EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD>ΪPEM<45>ַ<EFBFBD><D6B7><EFBFBD>
 | 
					
						
							|  |  |  |  | bool CBASE64::genKeyStrings(std::string& strPrivateKeyPEMString, std::string& strPublicKeyPEMString) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD>RSA
 | 
					
						
							|  |  |  |  |     RSA* rsa = (RSA*)__genKey(1024); | 
					
						
							|  |  |  |  |     if (rsa == NULL) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD>˽Կ
 | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         BIO* bio = BIO_new(BIO_s_mem()); | 
					
						
							|  |  |  |  |         int ret = PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL); | 
					
						
							|  |  |  |  |         if (ret != 1) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             BIO_free(bio); | 
					
						
							|  |  |  |  |             RSA_free(rsa); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         char sBuf[1024] = { 0 }; | 
					
						
							|  |  |  |  |         int bytes = BIO_read(bio, sBuf, 1024); | 
					
						
							|  |  |  |  |         if (bytes <= 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             BIO_free(bio); | 
					
						
							|  |  |  |  |             RSA_free(rsa); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         BIO_free(bio); | 
					
						
							|  |  |  |  |         strPrivateKeyPEMString.assign(sBuf, bytes); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Կ
 | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         BIO* bio = BIO_new(BIO_s_mem()); | 
					
						
							|  |  |  |  |         int ret = PEM_write_bio_RSAPublicKey(bio, rsa); | 
					
						
							|  |  |  |  |         if (ret != 1) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             BIO_free(bio); | 
					
						
							|  |  |  |  |             RSA_free(rsa); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         char sBuf[1024] = { 0 }; | 
					
						
							|  |  |  |  |         int bytes = BIO_read(bio, sBuf, 1024); | 
					
						
							|  |  |  |  |         if (bytes <= 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             BIO_free(bio); | 
					
						
							|  |  |  |  |             RSA_free(rsa); | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         BIO_free(bio); | 
					
						
							|  |  |  |  |         strPublicKeyPEMString.assign(sBuf, bytes); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     RSA_free(rsa); | 
					
						
							|  |  |  |  |     return true; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ʹ<><CAB9>PEM˽Կ<CBBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | bool CBASE64::encryptByPrivatePEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD>˽Կ
 | 
					
						
							|  |  |  |  |     BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size()); | 
					
						
							|  |  |  |  |     RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL); | 
					
						
							|  |  |  |  |     BIO_free(bio); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (rsa == NULL) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // ʹ<><CAB9>˽Կ<CBBD><D4BF><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |     bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_private_encrypt, true); | 
					
						
							|  |  |  |  |     RSA_free(rsa); | 
					
						
							|  |  |  |  |     return b; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ʹ<><CAB9>RSAִ<41>м<EFBFBD><D0BC>ܻ<EFBFBD><DCBB><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | bool CBASE64::__encryptOrDecrypt(const std::string& strIn, std::string& strOut, const void* pRSA, const void* pFunc, bool bEncrypt) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     const RSA_encryptOrDecrypt encryptOrDecrypt = (const RSA_encryptOrDecrypt)pFunc; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܿ<EFBFBD><DCBF><EFBFBD>С
 | 
					
						
							|  |  |  |  |     int nKeySize = RSA_size((RSA*)pRSA); | 
					
						
							|  |  |  |  |     int nBlockSize = bEncrypt ? (nKeySize - RSA_PKCS1_PADDING_SIZE) : nKeySize; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     const unsigned char* pIn = (const unsigned char*)strIn.data(); | 
					
						
							|  |  |  |  |     int nInSize = strIn.size(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     unsigned char* pBuf = new unsigned char[nKeySize]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |     for (int i = 0; i < nInSize; ) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         int nBlockLen = (nInSize - i > nBlockSize ? nBlockSize : nInSize - i); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int ret = encryptOrDecrypt(nBlockLen, pIn + i, pBuf, (RSA*)pRSA, RSA_PKCS1_PADDING); | 
					
						
							|  |  |  |  |         if (ret <= 0) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             delete[] pBuf; | 
					
						
							|  |  |  |  |             return false; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         strOut.append((char*)pBuf, ret); | 
					
						
							|  |  |  |  |         i += nBlockLen; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     delete[] pBuf; | 
					
						
							|  |  |  |  |     return true; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ʹ<><CAB9>PEM<45><4D>Կ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | bool CBASE64::encryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // <20><><EFBFBD>ع<EFBFBD>Կ
 | 
					
						
							|  |  |  |  |     BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size()); | 
					
						
							|  |  |  |  |     RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); | 
					
						
							|  |  |  |  |     BIO_free(bio); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (rsa == NULL) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // ʹ<>ù<EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |     bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_public_encrypt, true); | 
					
						
							|  |  |  |  |     RSA_free(rsa); | 
					
						
							|  |  |  |  |     return b; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ʹ<><CAB9>PEM<45><4D>Կ<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  | bool CBASE64::decryptByPublicPEMString(const std::string& strIn, std::string& strOut, const std::string& strKeyPEMString) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // <20><><EFBFBD>ع<EFBFBD>Կ
 | 
					
						
							|  |  |  |  |     BIO* bio = BIO_new_mem_buf((const void*)strKeyPEMString.data(), strKeyPEMString.size()); | 
					
						
							|  |  |  |  |     RSA* rsa = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL); | 
					
						
							|  |  |  |  |     BIO_free(bio); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (rsa == NULL) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С<EFBFBD>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |     int keySize = RSA_size(rsa); | 
					
						
							|  |  |  |  |     int blockSize = keySize; | 
					
						
							|  |  |  |  |     if ((strIn.size() % blockSize) != 0) | 
					
						
							|  |  |  |  |         return false; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // ʹ<>ù<EFBFBD>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>
 | 
					
						
							|  |  |  |  |     bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void*)RSA_public_decrypt, false); | 
					
						
							|  |  |  |  |     RSA_free(rsa); | 
					
						
							|  |  |  |  |     return b; | 
					
						
							|  |  |  |  | } |