2023年后,openssl进入3.0版本,openssl的加解密代码也出现了一些变化,例如编译时会有如下错误:
error C4996: ‘AES_set_encrypt_key’: Since OpenSSL 3.0
如果使用OpenSSL 1.1.1 sdk编译则没有上述错误,使用3.0以上的openssl sdk就会报错,那是因为3.0的不兼容1.0的sdk。如果你想继续使用已弃用的函数,并且不想更改代码,可以考虑禁用特定的编译警告。在 Visual Studio 中,你可以使用 #pragma warning(disable: 4996)
来禁用这个特定的警告。请注意,这并不是一个推荐的解决方案,因为它可能会掩盖潜在的问题。最佳的解决方案通常是更新你的代码,以使用新的API。这样可以确保你的代码与最新的库版本兼容,并且可以从新版本中获得的安全和性能改进中受益。
下面是C++ OpenSSL 3.0 AES加解密的代码:文章来源:https://www.toymoban.com/news/detail-663361.html
#pragma once
#include <iostream>
#include <vector>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <string>
#include <codecvt>
#include <sstream>
#include <iomanip>
class CEncrypt3 {
private:
CEncrypt3() {
const unsigned char fixed_key[32] = { 0x71, 0x02, 0x03, 0x04, 0x05, 0x06, 0x17, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x4A, 0x0F, 0x10,
0x11, 0x12, 0x53, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0xFC, 0x10, 0x1E, 0x1F, 0x20 };
const unsigned char fixed_iv[16] = { 0x21, 0x02, 0x03, 0xA4, 0x05, 0x06, 0x23, 0x08, 0x09, 0x0A, 0x1B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };
std::copy(fixed_key, fixed_key + sizeof(key), key);
std::copy(fixed_iv, fixed_iv + sizeof(iv), iv);
}
public:
static CEncrypt3& Instance() {
static CEncrypt3 instance;
return instance;
}
CEncrypt3(const CEncrypt3&) = delete;
CEncrypt3& operator=(const CEncrypt3&) = delete;
std::wstring Encrypt(const std::wstring& plaintext)
{
if (plaintext.empty())
return L"";
std::vector<unsigned char> ciphertext;
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx)
{
throw std::runtime_error("Failed to create cipher context");
}
if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to initialize encryption");
}
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
std::string utf8_text = converter.to_bytes(plaintext);
int len;
ciphertext.resize(utf8_text.size() + EVP_CIPHER_block_size(EVP_aes_256_cbc()));
if (EVP_EncryptUpdate(ctx, ciphertext.data(), &len, reinterpret_cast<const unsigned char*>(utf8_text.data()), utf8_text.size()) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to encrypt data");
}
int padding_len;
if (EVP_EncryptFinal_ex(ctx, ciphertext.data() + len, &padding_len) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to finalize encryption");
}
ciphertext.resize(len + padding_len);
EVP_CIPHER_CTX_free(ctx);
std::wstringstream wss;
for (auto c : ciphertext) {
wss << std::hex << std::setw(2) << std::setfill(L'0') << (int)c;
}
return wss.str();
}
std::wstring Decrypt(const std::wstring& ciphertext)
{
if (ciphertext.empty())
return L"";
std::vector<unsigned char> ciphertext_bytes;
for (size_t i = 0; i < ciphertext.size(); i += 2) {
std::wstring byte_string = ciphertext.substr(i, 2);
unsigned char byte = static_cast<unsigned char>(std::stoi(byte_string, nullptr, 16));
ciphertext_bytes.push_back(byte);
}
std::vector<unsigned char> plaintext;
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
if (!ctx)
{
throw std::runtime_error("Failed to create cipher context");
}
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to initialize decryption");
}
int len;
plaintext.resize(ciphertext_bytes.size());
if (EVP_DecryptUpdate(ctx, plaintext.data(), &len, ciphertext_bytes.data(), ciphertext_bytes.size()) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to decrypt data");
}
int padding_len;
if (EVP_DecryptFinal_ex(ctx, plaintext.data() + len, &padding_len) != 1)
{
EVP_CIPHER_CTX_free(ctx);
throw std::runtime_error("Failed to finalize decryption");
}
plaintext.resize(len + padding_len);
EVP_CIPHER_CTX_free(ctx);
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
return converter.from_bytes(reinterpret_cast<const char*>(plaintext.data()), reinterpret_cast<const char*>(plaintext.data() + plaintext.size()));
}
private:
unsigned char key[32];
unsigned char iv[16];
};
int main()
{
CEncrypt3& instance = CEncrypt3::Instance();
std::wstring plaintext = L"中文加密解密容易出现乱码";
std::wstring ciphertext = instance.Encrypt(plaintext);
std::wstring decrypted_text = instance.Decrypt(ciphertext);
std::wcout << L"Original text: " << plaintext << std::endl;
std::wcout << L"Decrypted text: " << decrypted_text << std::endl;
return 0;
}
CEncrypt3用了单例模式,在其它地方调用时,使用CEncrypt3::Instance().Encrypt(plaintext)即可。文章来源地址https://www.toymoban.com/news/detail-663361.html
到了这里,关于C++ OpenSSL 3.0.8 AES加解密的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!