#ifndef _ENCRYPT_RC4_ #define _ENCRYPT_RC4_ #include #include #include #include #include #include #include #include #include "log.hpp" #include "obfuscate.hpp" #define BOX_LEN 256 int GetKey(const unsigned char *pass, int pass_len, unsigned char *out); // 十六进制编码 std::string hex_encode(const std::string& input); // 十六进制解码 std::string hex_decode(const std::string& encoded); int RC4(const unsigned char *data, int data_len, const unsigned char *key, int key_len, unsigned char *out, int *out_len); static void swap_byte(unsigned char *a, unsigned char *b); char *Encrypt(const char *szSource, const char *szPassWord); // 加密,返回加密结果 char *Decrypt(const char *szSource, const char *szPassWord); // 解密,返回解密结果 std::string RSA_Encrypt(const std::string& plaintext, const std::string& publicKeyPEM); std::string RSA_Decrypt(const std::string& encrypted, const std::string& privateKeyPEM); char *ByteToHex(const unsigned char *vByte, const int vLen); // 把字节码pbBuffer转为十六进制字符串,方便传输 unsigned char *HexToByte(const char *szHex); // 把十六进制字符串转为字节码pbBuffer,解码 #endif // #ifndef _ENCRYPT_RC4_ char *Encrypt(const char *szSource, const char *szPassWord) // 加密,返回加密结果 { if (szSource == NULL || szPassWord == NULL) return NULL; unsigned char *ret = new unsigned char[strlen(szSource)]; int ret_len = 0; if (RC4((unsigned char *) szSource, strlen(szSource), (unsigned char *) szPassWord, strlen(szPassWord), ret, &ret_len) == 0) return NULL; char *ret2 = ByteToHex(ret, ret_len); delete[] ret; return ret2; } char *Decrypt(const char *szSource, const char *szPassWord) // 解密,返回解密结果 { if (szSource == NULL || (strlen(szSource) % 2 != 0) || szPassWord == NULL) return NULL; unsigned char *src = HexToByte(szSource); unsigned char *ret = new unsigned char[strlen(szSource) / 2 + 1]; int ret_len = 0; memset(ret, strlen(szSource) / 2 + 1, 0); if (RC4(src, strlen(szSource) / 2, (unsigned char *) szPassWord, strlen(szPassWord), ret, &ret_len) == 0) return NULL; ret[ret_len] = '\0'; return (char *) ret; } // 十六进制编码 std::string hex_encode(const std::string& input) { std::stringstream ss; for (size_t i = 0; i < input.size(); i++) { ss << std::hex << std::setw(2) << std::setfill('0') << (int)(unsigned char)input[i]; } return ss.str(); } // 十六进制解码 std::string hex_decode(const std::string& encoded) { std::string result; for (size_t i = 0; i < encoded.length(); i += 2) { std::string byteString = encoded.substr(i, 2); char byte = (char)strtol(byteString.c_str(), NULL, 16); result.push_back(byte); } return result; } // RSA 加密(使用 EVP_PKEY) std::string RSA_Encrypt(const std::string& plaintext, const std::string& publicKeyPEM) { BIO* bio = BIO_new_mem_buf(publicKeyPEM.data(), -1); // 使用 -1 自动检测长度 if (!bio) { // 无法创建 BIO 对象 LOG_DEBUG("无法创建 BIO 对象"); return ""; } EVP_PKEY* publicKey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr); BIO_free(bio); if (!publicKey) { // 无法加载公钥 LOG_DEBUG ("无法加载公钥"); return ""; } EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(publicKey, NULL); if (!ctx) { // 无法创建 EVP_PKEY_CTX LOG_DEBUG ("无法创建 EVP_PKEY_CTX"); EVP_PKEY_free(publicKey); return ""; } if (EVP_PKEY_encrypt_init(ctx) <= 0) { // 初始化加密失败 LOG_DEBUG ("初始化加密失败"); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(publicKey); return ""; } size_t outlen; unsigned char* encrypted = (unsigned char*)malloc(EVP_PKEY_size(publicKey)); if (EVP_PKEY_encrypt(ctx, encrypted, &outlen, (unsigned char*)plaintext.data(), plaintext.size()) <= 0) { // 加密失败 LOG_DEBUG ("加密失败"); free(encrypted); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(publicKey); return ""; } std::string encryptedStr((char*)encrypted, outlen); free(encrypted); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(publicKey); return hex_encode(encryptedStr); } // RSA 解密(使用 EVP_PKEY) std::string RSA_Decrypt(const std::string& encrypted, const std::string& privateKeyPEM) { BIO* bio = BIO_new_mem_buf(privateKeyPEM.data(), -1); if (!bio) { // 无法创建 BIO 对象 return ""; } EVP_PKEY* privateKey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); BIO_free(bio); if (!privateKey) { // 无法加载私钥 return ""; } EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(privateKey, NULL); if (!ctx) { // 无法创建 EVP_PKEY_CTX EVP_PKEY_free(privateKey); return ""; } if (EVP_PKEY_decrypt_init(ctx) <= 0) { // 初始化解密失败 EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(privateKey); return ""; } size_t outlen; unsigned char* decrypted = (unsigned char*)malloc(EVP_PKEY_size(privateKey)); if (EVP_PKEY_decrypt(ctx, decrypted, &outlen, (unsigned char*)hex_decode(encrypted).data(), hex_decode(encrypted).size()) <= 0) { // 解密失败 free(decrypted); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(privateKey); return ""; } std::string decryptedStr((char*)decrypted, outlen); free(decrypted); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(privateKey); return decryptedStr; } int RC4(const unsigned char *data, int data_len, const unsigned char *key, int key_len, unsigned char *out, int *out_len) { if (data == NULL || key == NULL || out == NULL) return 0; unsigned char *mBox = new unsigned char[BOX_LEN]; if (GetKey(key, key_len, mBox) == 0) return 0; int i = 0; int x = 0; int y = 0; for (int k = 0; k < data_len; k++) { x = (x + 1) % BOX_LEN; y = (mBox[x] + y) % BOX_LEN; swap_byte(&mBox[x], &mBox[y]); out[k] = data[k] ^ mBox[(mBox[x] + mBox[y]) % BOX_LEN]; } *out_len = data_len; delete[] mBox; return -1; } int GetKey(const unsigned char *pass, int pass_len, unsigned char *out) { if (pass == NULL || out == NULL) return 0; int i; for (i = 0; i < BOX_LEN; i++) out[i] = i; int j = 0; for (i = 0; i < BOX_LEN; i++) { j = (pass[i % pass_len] + out[i] + j) % BOX_LEN; swap_byte(&out[i], &out[j]); } return -1; } static void swap_byte(unsigned char *a, unsigned char *b) { unsigned char swapByte; swapByte = *a; *a = *b; *b = swapByte; } // 把字节码转为十六进制码,一个字节两个十六进制,内部为字符串分配空间 char *ByteToHex(const unsigned char *vByte, const int vLen) { if (!vByte) return NULL; char *tmp = new char[vLen * 2 + 1]; // 一个字节两个十六进制码,最后要多一个'\0' int tmp2; for (int i = 0; i < vLen; i++) { tmp2 = (int) (vByte[i]) / 16; tmp[i * 2] = (char) (tmp2 + ((tmp2 > 9) ? 'a' - 10 : '0')); tmp2 = (int) (vByte[i]) % 16; tmp[i * 2 + 1] = (char) (tmp2 + ((tmp2 > 9) ? 'a' - 10 : '0')); } tmp[vLen * 2] = '\0'; return tmp; } // 把十六进制字符串,转为字节码,每两个十六进制字符作为一个字节 unsigned char *HexToByte(const char *szHex) { if (!szHex) return NULL; int iLen = strlen(szHex); if (iLen <= 0 || 0 != iLen % 2) return NULL; unsigned char *pbBuf = new unsigned char[iLen / 2]; // 数据缓冲区 int tmp1, tmp2; for (int i = 0; i < iLen / 2; i++) { tmp1 = (int) szHex[i * 2] - (((int) szHex[i * 2] >= 'a') ? 'a' - 10 : '0'); if (tmp1 >= 16) return NULL; tmp2 = (int) szHex[i * 2 + 1] - (((int) szHex[i * 2 + 1] >= 'a') ? 'a' - 10 : '0'); if (tmp2 >= 16) return NULL; pbBuf[i] = (tmp1 * 16 + tmp2); } return pbBuf; }