#ifndef __DAKUANG_BASE64_H__ #define __DAKUANG_BASE64_H__ #include #include #include #include namespace LenheartBase { class CBASE64 { public: // 生成RSA密钥结构 static void *__genKey(int nBits); // 生成密钥对,输出为PEM字符串 static bool genKeyStrings(std::string &strPrivateKeyPEMString, std::string &strPublicKeyPEMString); // 执行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); // 使用PEM私钥字符串加密 static bool encryptByPrivatePEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString); // 使用PEM公钥字符串加密 static bool encryptByPublicPEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString); // 使用PEM公钥字符串解密 static bool decryptByPublicPEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString); // 使用RSA执行加密或解密 static bool __encryptOrDecrypt(const std::string &strIn, std::string &strOut, const void *pRSA, const void *pFunc, bool bEncrypt); 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[]; }; } using namespace LenheartBase; // 加解密函数签名 typedef int (*RSA_encryptOrDecrypt)(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); // 编解码转换表 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; } // 生成RSA密钥结构 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; } // 生成密钥对,输出为PEM字符串 bool CBASE64::genKeyStrings(std::string &strPrivateKeyPEMString, std::string &strPublicKeyPEMString) { // 生成RSA RSA *rsa = (RSA *)__genKey(1024); if (rsa == NULL) return false; // 输出私钥 { 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); } // 输出公钥 { 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; } // 使用PEM私钥字符串加密 bool CBASE64::encryptByPrivatePEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString) { // 加载私钥 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; // 使用私钥加密 bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void *)RSA_private_encrypt, true); RSA_free(rsa); return b; } // 使用RSA执行加密或解密 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; // 计算加密块大小 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]; // 分组迭代加密 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; } // 使用PEM公钥字符串加密 bool CBASE64::encryptByPublicPEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString) { // 加载公钥 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; // 使用公钥加密 bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void *)RSA_public_encrypt, true); RSA_free(rsa); return b; } // 使用PEM公钥字符串解密 bool CBASE64::decryptByPublicPEMString(const std::string &strIn, std::string &strOut, const std::string &strKeyPEMString) { // 加载公钥 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; // 检查密文大小是否为分组的整数倍 int keySize = RSA_size(rsa); int blockSize = keySize; if ((strIn.size() % blockSize) != 0) return false; // 使用公钥解密 bool b = __encryptOrDecrypt(strIn, strOut, rsa, (const void *)RSA_public_decrypt, false); RSA_free(rsa); return b; } #endif