Files
micro_servers/libcrypt/inc/us/AES_CBC.hpp
T
2026-07-20 11:12:29 +08:00

141 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Crypto_Basic.hpp"
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <iostream>
#include <vector>
#include <stdexcept>
namespace qing {
class AES_CBC: public qing::Crypto_Basic {
public:
/* 构造函数 初始化一个随即的密钥和初始化向量 */
AES_CBC() {
generate_key_iv(key, iv);
}
AES_CBC(std::vector<unsigned char> &key, std::vector<unsigned char> &iv) {
this->key = key;
this->iv = iv;
}
std::string get_key() {
return bytes_to_hex(key);
}
std::string get_iv() {
return bytes_to_hex(iv);
}
std::string encrypt(std::string original_text) {
std::vector<unsigned char> plaintext(original_text.begin(), original_text.end());
std::vector<unsigned char> ciphertext = aes_encrypt(plaintext, key, iv);
// hex-bytes转换测试
/*std::string hex = bytes_to_hex(ciphertext);
std::vector<unsigned char> cipher2 = hex_to_bytes(hex);
print_bytes(ciphertext);
print_bytes(cipher2);*/
return bytes_to_hex(ciphertext);
}
std::string decrypt(std::string cipher_hex) {
std::vector<unsigned char> ciphertext = hex_to_bytes(cipher_hex);
std::vector<unsigned char> decrypted = aes_decrypt(ciphertext, key, iv);
return std::string(decrypted.begin(), decrypted.end());
}
static void print_bytes(std::vector<unsigned char>& bytes) {
for (unsigned char byte : bytes) {
std::cerr << std::setw(2) << static_cast<int>(byte);
}
std::cerr << std::endl;
}
private:
std::vector<unsigned char> key;
std::vector<unsigned char> iv;
// 生成随机密钥和IV
static void generate_key_iv(std::vector<unsigned char>& key,
std::vector<unsigned char>& iv) {
key.resize(32); // AES-256 需要 32 字节密钥
iv.resize(16); // AES 块大小 16 字节(128-bit)
// 生成随即密钥
CRYPTO_CHECK(RAND_bytes(key.data(), key.size()) == 1, "密钥生成失败");
// 生成随即IV
CRYPTO_CHECK(RAND_bytes(iv.data(), iv.size()) == 1, "IV生成失败");
}
// AES-256-CBC 加密
static std::vector<unsigned char> aes_encrypt(const std::vector<unsigned char>& plaintext,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv) {
// 创建上下文
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
CRYPTO_CHECK(ctx != nullptr, "无法创建加密上下文");
// 初始化加密操作
CRYPTO_CHECK(EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr,
key.data(), iv.data()) , "加密初始化失败");
// 输出缓冲区 (密文可能比明文长一个块)
std::vector<unsigned char> ciphertext(plaintext.size() + EVP_CIPHER_CTX_block_size(ctx));
int len = 0;
int ciphertext_len = 0;
// 提供明文数据
CRYPTO_CHECK(EVP_EncryptUpdate(ctx, ciphertext.data(), &len,
plaintext.data(), plaintext.size()) == 1, "加载更新失败");
ciphertext_len = len;
// 完成加密(处理填充)
CRYPTO_CHECK(EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &len) == 1, "加密结束失败");
ciphertext_len += len;
// 调整到实际密文长度
ciphertext.resize(ciphertext_len);
// 处理上下文
EVP_CIPHER_CTX_free(ctx);
return ciphertext;
}
// AES-256-CBC
static std::vector<unsigned char> aes_decrypt(const std::vector<unsigned char>& ciphertext,
const std::vector<unsigned char>& key,
const std::vector<unsigned char>& iv) {
// 创建上下文
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
CRYPTO_CHECK(ctx != nullptr, "无法创建解密上下文");
// 初始化解密操作
CRYPTO_CHECK(EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr,
key.data(), iv.data()) == 1, "解密初始化失败");
// 输出缓冲区(明文可能比密文短,但最大为密文长度)
std::vector<unsigned char> plaintext(ciphertext.size());
int len = 0;
int plaintext_len = 0;
// 提供密文数据
CRYPTO_CHECK(EVP_DecryptUpdate(ctx, plaintext.data(), &len,
ciphertext.data(), ciphertext.size()) == 1, "解密更新失败");
plaintext_len = len;
// 完成解密(处理填充)
CRYPTO_CHECK(EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &len) == 1, "解密结束失败");
plaintext_len += len;
// 调整到实际明文长度
plaintext.resize(plaintext_len);
// 清理上下文
EVP_CIPHER_CTX_free(ctx);
return plaintext;
}
};
}