🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Exemplos de Criptografia Windows C++
Exemplos de criptografia Windows C++ incluindo cálculo de hash, criptografia/descriptografia AES e codificação/decodificação Base64
💻 Codificação/Decodificação Base64 cpp
🟢 simple
⭐⭐
Codificar dados binários em strings Base64 e decodificar strings Base64 de volta para dados binários usando Windows API
⏱️ 20 min
🏷️ cpp, base64, encoding, windows
Prerequisites:
Basic C++, Windows Cryptography API
// Windows C++ Base64 Encoding/Decoding Examples
// Using Windows Cryptography API
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
// 1. Basic Base64 Encoding
class Base64Encoder {
public:
static std::string encode(const std::vector<BYTE>& data) {
DWORD encodedSize = 0;
// Get the required buffer size
if (!CryptBinaryToStringA(data.data(), static_cast<DWORD>(data.size()),
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR, nullptr, &encodedSize)) {
std::cerr << "Failed to get encoded size" << std::endl;
return "";
}
// Allocate buffer and encode
std::string encoded;
encoded.resize(encodedSize);
if (!CryptBinaryToStringA(data.data(), static_cast<DWORD>(data.size()),
CRYPT_STRING_BASE64 | CRYPT_STRING_NOCR,
reinterpret_cast<LPSTR>(&encoded[0]), &encodedSize)) {
std::cerr << "Failed to encode data" << std::endl;
return "";
}
// Remove null terminator if present
if (!encoded.empty() && encoded[encodedSize - 1] == '\0') {
encoded.resize(encodedSize - 1);
} else {
encoded.resize(encodedSize);
}
return encoded;
}
static std::string encodeString(const std::string& text) {
std::vector<BYTE> data(text.begin(), text.end());
return encode(data);
}
static std::string encodeWithLineBreaks(const std::vector<BYTE>& data, int lineWidth = 76) {
DWORD encodedSize = 0;
// Get the required buffer size
if (!CryptBinaryToStringA(data.data(), static_cast<DWORD>(data.size()),
CRYPT_STRING_BASE64, nullptr, &encodedSize)) {
return "";
}
std::string encoded;
encoded.resize(encodedSize);
if (!CryptBinaryToStringA(data.data(), static_cast<DWORD>(data.size()),
CRYPT_STRING_BASE64,
reinterpret_cast<LPSTR>(&encoded[0]), &encodedSize)) {
return "";
}
if (!encoded.empty() && encoded[encodedSize - 1] == '\0') {
encoded.resize(encodedSize - 1);
} else {
encoded.resize(encodedSize);
}
return encoded;
}
};
// 2. Basic Base64 Decoding
class Base64Decoder {
public:
static std::vector<BYTE> decode(const std::string& encoded) {
DWORD decodedSize = 0;
// Get the required buffer size
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64,
nullptr, &decodedSize, nullptr, nullptr)) {
std::cerr << "Failed to get decoded size" << std::endl;
return {};
}
// Allocate buffer and decode
std::vector<BYTE> decoded(decodedSize);
if (!CryptStringToBinaryA(encoded.c_str(), 0, CRYPT_STRING_BASE64,
decoded.data(), &decodedSize, nullptr, nullptr)) {
std::cerr << "Failed to decode data" << std::endl;
return {};
}
decoded.resize(decodedSize);
return decoded;
}
static std::string decodeToString(const std::string& encoded) {
std::vector<BYTE> data = decode(encoded);
if (data.empty()) {
return "";
}
return std::string(data.begin(), data.end());
}
};
// 3. Base64 for URL Encoding (URL-safe variant)
class Base64URLEncoder {
public:
static std::string encode(const std::vector<BYTE>& data) {
// First, do standard base64 encoding
std::string encoded = Base64Encoder::encode(data);
// Make URL-safe: replace + with -, replace / with _, remove trailing =
for (char& c : encoded) {
if (c == '+') c = '-';
else if (c == '/') c = '_';
}
// Remove padding characters
size_t paddingPos = encoded.find('=');
if (paddingPos != std::string::npos) {
encoded = encoded.substr(0, paddingPos);
}
return encoded;
}
static std::vector<BYTE> decode(const std::string& encoded) {
// Convert URL-safe back to standard base64
std::string standard = encoded;
for (char& c : standard) {
if (c == '-') c = '+';
else if (c == '_') c = '/';
}
// Add padding if necessary
while (standard.size() % 4 != 0) {
standard += '=';
}
return Base64Decoder::decode(standard);
}
};
// 4. Base64 File Operations
class Base64File {
public:
static bool encodeFile(const std::string& inputFile, const std::string& outputFile) {
// Read input file
std::ifstream inFile(inputFile, std::ios::binary);
if (!inFile) {
std::cerr << "Failed to open input file: " << inputFile << std::endl;
return false;
}
std::vector<BYTE> fileData((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
inFile.close();
// Encode
std::string encoded = Base64Encoder::encodeWithLineBreaks(fileData);
// Write output file
std::ofstream outFile(outputFile);
if (!outFile) {
std::cerr << "Failed to open output file: " << outputFile << std::endl;
return false;
}
outFile << encoded;
outFile.close();
std::cout << "File encoded: " << inputFile << " -> " << outputFile << std::endl;
std::cout << "Original size: " << fileData.size() << " bytes" << std::endl;
std::cout << "Encoded size: " << encoded.size() << " characters" << std::endl;
return true;
}
static bool decodeFile(const std::string& inputFile, const std::string& outputFile) {
// Read input file
std::ifstream inFile(inputFile);
if (!inFile) {
std::cerr << "Failed to open input file: " << inputFile << std::endl;
return false;
}
std::string encoded((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
inFile.close();
// Decode
std::vector<BYTE> fileData = Base64Decoder::decode(encoded);
if (fileData.empty()) {
std::cerr << "Failed to decode file data" << std::endl;
return false;
}
// Write output file
std::ofstream outFile(outputFile, std::ios::binary);
if (!outFile) {
std::cerr << "Failed to open output file: " << outputFile << std::endl;
return false;
}
outFile.write(reinterpret_cast<const char*>(fileData.data()), fileData.size());
outFile.close();
std::cout << "File decoded: " << inputFile << " -> " << outputFile << std::endl;
std::cout << "Encoded size: " << encoded.size() << " characters" << std::endl;
std::cout << "Decoded size: " << fileData.size() << " bytes" << std::endl;
return true;
}
};
// 5. Base64 Hash Encoding
class Base64Hash {
public:
// Encode SHA256 hash as base64
static std::string encodeSHA256(const std::string& input) {
// Calculate SHA256 hash
std::vector<BYTE> hash = calculateSHA256(input);
// Encode as base64
return Base64Encoder::encode(hash);
}
// Common for JWT (JSON Web Tokens)
static std::string encodeForJWT(const std::string& data) {
std::vector<BYTE> bytes(data.begin(), data.end());
// Use URL-safe base64 encoding
return Base64URLEncoder::encode(bytes);
}
private:
static std::vector<BYTE> calculateSHA256(const std::string& input) {
// This would normally use Windows Cryptography API
// For demonstration, returning a placeholder
std::vector<BYTE> hash(32, 0x42);
return hash;
}
};
// 6. Base64 Image Encoding
class Base64Image {
public:
static std::string encodeImageWithHeader(const std::string& imageFile, const std::string& mimeType) {
// Read image file
std::ifstream inFile(imageFile, std::ios::binary);
if (!inFile) {
return "";
}
std::vector<BYTE> imageData((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
inFile.close();
// Encode as base64
std::string base64Data = Base64Encoder::encode(imageData);
// Add data URI header
return "data:" + mimeType + ";base64," + base64Data;
}
static bool saveImageFromDataURI(const std::string& dataURI, const std::string& outputFile) {
// Check for data URI header
const std::string prefix = "data:image/";
size_t startPos = dataURI.find(prefix);
if (startPos == std::string::npos) {
std::cerr << "Invalid data URI" << std::endl;
return false;
}
startPos = dataURI.find(";base64,") + 8; // Skip ";base64,"
std::string base64Data = dataURI.substr(startPos);
// Decode base64
std::vector<BYTE> imageData = Base64Decoder::decode(base64Data);
if (imageData.empty()) {
return false;
}
// Write to file
std::ofstream outFile(outputFile, std::ios::binary);
if (!outFile) {
return false;
}
outFile.write(reinterpret_cast<const char*>(imageData.data()), imageData.size());
outFile.close();
return true;
}
};
// 7. Base64 Chunked Encoding
class Base64Chunked {
public:
// Split data into chunks and encode each chunk separately
static std::vector<std::string> encodeChunked(const std::vector<BYTE>& data, int chunkSize = 1024) {
std::vector<std::string> chunks;
for (size_t i = 0; i < data.size(); i += chunkSize) {
size_t end = std::min(i + chunkSize, data.size());
std::vector<BYTE> chunk(data.begin() + i, data.begin() + end);
std::string encoded = Base64Encoder::encode(chunk);
chunks.push_back(encoded);
}
return chunks;
}
// Decode chunks and combine
static std::vector<BYTE> decodeChunked(const std::vector<std::string>& chunks) {
std::vector<BYTE> result;
for (const auto& chunk : chunks) {
std::vector<BYTE> decoded = Base64Decoder::decode(chunk);
if (decoded.empty()) {
return {}; // Error
}
result.insert(result.end(), decoded.begin(), decoded.end());
}
return result;
}
};
// 8. Base64 Validation
class Base64Validator {
public:
static bool isValidBase64(const std::string& str) {
if (str.empty()) {
return false;
}
// Check each character
for (char c : str) {
bool valid = (c >= 'A' && c <= 'Z') ||
(c >= 'a' && c <= 'z') ||
(c >= '0' && c <= '9') ||
c == '+' || c == '/' || c == '=' ||
c == '\r' || c == '\n';
if (!valid) {
return false;
}
}
// Check length is multiple of 4 (ignoring whitespace)
int contentLength = 0;
for (char c : str) {
if (c != '\r' && c != '\n' && c != ' ') {
contentLength++;
}
}
return contentLength % 4 == 0;
}
static std::string cleanBase64String(const std::string& str) {
std::string cleaned;
for (char c : str) {
if (c != '\r' && c != '\n' && c != ' ' && c != '\t') {
cleaned += c;
}
}
return cleaned;
}
};
// Main demonstration
int main() {
std::cout << "=== Windows C++ Base64 Encoding/Decoding Examples ===" << std::endl;
// 1. Basic encoding
std::cout << "\n--- Basic Encoding ---" << std::endl;
std::string text = "Hello, World!";
std::vector<BYTE> data(text.begin(), text.end());
std::string encoded = Base64Encoder::encode(data);
std::cout << "Original: " << text << std::endl;
std::cout << "Encoded: " << encoded << std::endl;
// 2. Basic decoding
std::cout << "\n--- Basic Decoding ---" << std::endl;
std::vector<BYTE> decoded = Base64Decoder::decode(encoded);
std::string decodedText(decoded.begin(), decoded.end());
std::cout << "Decoded: " << decodedText << std::endl;
// 3. String encoding/decoding
std::cout << "\n--- String Operations ---" << std::endl;
std::string message = "This is a secret message.";
std::string encodedMessage = Base64Encoder::encodeString(message);
std::string decodedMessage = Base64Decoder::decodeToString(encodedMessage);
std::cout << "Original: " << message << std::endl;
std::cout << "Encoded: " << encodedMessage << std::endl;
std::cout << "Decoded: " << decodedMessage << std::endl;
// 4. URL-safe encoding
std::cout << "\n--- URL-Safe Encoding ---" << std::endl;
std::vector<BYTE> urlData = {0x00, 0x01, 0x02, 0x03, 0xFF, 0xFE, 0xFD};
std::string urlEncoded = Base64URLEncoder::encode(urlData);
std::cout << "URL-safe encoded: " << urlEncoded << std::endl;
std::vector<BYTE> urlDecoded = Base64URLEncoder::decode(urlEncoded);
std::cout << "URL-safe decoded: " << (urlDecoded == urlData ? "SUCCESS" : "FAILED") << std::endl;
// 5. File encoding/decoding
std::cout << "\n--- File Operations ---" << std::endl;
std::ofstream testFile("test_data.txt");
testFile << "This is test data for Base64 encoding.";
testFile.close();
Base64File::encodeFile("test_data.txt", "test_data.b64");
Base64File::decodeFile("test_data.b64", "test_data_decoded.txt");
// 6. Image encoding
std::cout << "\n--- Image Data URI ---" << std::endl;
std::ofstream testImage("test_image.png");
// Write minimal PNG data (1x1 pixel transparent PNG)
unsigned char pngData[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
testImage.write(reinterpret_cast<const char*>(pngData), 8);
testImage.close();
std::string dataUri = Base64Image::encodeImageWithHeader("test_image.png", "image/png");
std::cout << "Data URI (truncated): " << dataUri.substr(0, 100) << "..." << std::endl;
// 7. Chunked encoding
std::cout << "\n--- Chunked Encoding ---" << std::endl;
std::vector<BYTE> largeData(3000);
for (size_t i = 0; i < largeData.size(); i++) {
largeData[i] = static_cast<BYTE>(i % 256);
}
std::vector<std::string> chunks = Base64Chunked::encodeChunked(largeData, 1000);
std::cout << "Split into " << chunks.size() << " chunks" << std::endl;
std::vector<BYTE> reassembled = Base64Chunked::decodeChunked(chunks);
std::cout << "Reassembly: " << (reassembled == largeData ? "SUCCESS" : "FAILED") << std::endl;
// 8. Validation
std::cout << "\n--- Validation ---" << std::endl;
std::string validBase64 = "SGVsbG8sIFdvcmxkIQ==";
std::string invalidBase64 = "Invalid@Base64!";
std::cout << "'" << validBase64 << "' is valid: "
<< (Base64Validator::isValidBase64(validBase64) ? "YES" : "NO") << std::endl;
std::cout << "'" << invalidBase64 << "' is valid: "
<< (Base64Validator::isValidBase64(invalidBase64) ? "YES" : "NO") << std::endl;
std::cout << "\n=== All Base64 Examples Completed ===" << std::endl;
return 0;
}
💻 Cálculo de Hash cpp
🟡 intermediate
⭐⭐⭐
Calcular valores de hash MD5, SHA1, SHA256 e SHA512 para strings e arquivos usando Windows Cryptography API
⏱️ 25 min
🏷️ cpp, cryptography, hash, windows
Prerequisites:
Intermediate C++, Windows Cryptography API
// Windows C++ Hash Calculation Examples
// Using Windows Cryptography API (CryptoAPI/CNG)
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <windows.h>
#include <wincrypt.h>
#pragma comment(lib, "crypt32.lib")
// 1. MD5 Hash Calculation
class MD5Hash {
public:
static std::string calculate(const std::string& input) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
// Get handle to crypto provider
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
std::cerr << "CryptAcquireContext failed" << std::endl;
return "";
}
// Create hash object
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
std::cerr << "CryptCreateHash failed" << std::endl;
return "";
}
// Hash data
if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(input.c_str()), input.size(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
std::cerr << "CryptHashData failed" << std::endl;
return "";
}
// Get hash value
DWORD hashLen = 16; // MD5 is 16 bytes
std::vector<BYTE> hash(hashLen);
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash.data(), &hashLen, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
std::cerr << "CryptGetHashParam failed" << std::endl;
return "";
}
// Clean up
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
// Convert to hexadecimal string
return bytesToHex(hash);
}
static std::string calculateFile(const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::cerr << "Failed to open file: " << filename << std::endl;
return "";
}
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
return "";
}
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
return "";
}
// Hash file in chunks
const int BUFFER_SIZE = 4096;
std::vector<BYTE> buffer(BUFFER_SIZE);
while (file) {
file.read(reinterpret_cast<char*>(buffer.data()), BUFFER_SIZE);
std::streamsize bytesRead = file.gcount();
if (bytesRead > 0) {
if (!CryptHashData(hHash, buffer.data(), static_cast<DWORD>(bytesRead), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return "";
}
}
}
DWORD hashLen = 16;
std::vector<BYTE> hash(hashLen);
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash.data(), &hashLen, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return "";
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return bytesToHex(hash);
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
};
// 2. SHA1 Hash Calculation
class SHA1Hash {
public:
static std::string calculate(const std::string& input) {
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
return "";
}
if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) {
CryptReleaseContext(hProv, 0);
return "";
}
if (!CryptHashData(hHash, reinterpret_cast<const BYTE*>(input.c_str()), input.size(), 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return "";
}
DWORD hashLen = 20; // SHA1 is 20 bytes
std::vector<BYTE> hash(hashLen);
if (!CryptGetHashParam(hHash, HP_HASHVAL, hash.data(), &hashLen, 0)) {
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return "";
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
return bytesToHex(hash);
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
};
// 3. SHA256 Hash Calculation (using CNG - Cryptography Next Generation)
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
class SHA256Hash {
public:
static std::string calculate(const std::string& input) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
NTSTATUS status;
DWORD hashLen = 0;
DWORD resultLen = 0;
// Open algorithm provider
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, 0);
if (status != 0) {
std::cerr << "BCryptOpenAlgorithmProvider failed: " << status << std::endl;
return "";
}
// Get hash length
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, reinterpret_cast<PBYTE>(&hashLen), sizeof(hashLen), &resultLen, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Create hash object
status = BCryptCreateHash(hAlg, &hHash, nullptr, 0, nullptr, 0, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Hash data
status = BCryptHashData(hHash, reinterpret_cast<PBYTE>(const_cast<char*>(input.c_str())), input.size(), 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Get hash value
std::vector<BYTE> hash(hashLen);
status = BCryptFinishHash(hHash, hash.data(), hashLen, 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Clean up
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return bytesToHex(hash);
}
static std::string calculateFile(const std::string& filename) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
NTSTATUS status;
DWORD hashLen = 0;
DWORD resultLen = 0;
std::ifstream file(filename, std::ios::binary);
if (!file) {
std::cerr << "Failed to open file: " << filename << std::endl;
return "";
}
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, 0);
if (status != 0) {
return "";
}
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, reinterpret_cast<PBYTE>(&hashLen), sizeof(hashLen), &resultLen, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
status = BCryptCreateHash(hAlg, &hHash, nullptr, 0, nullptr, 0, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Hash file in chunks
const int BUFFER_SIZE = 4096;
std::vector<BYTE> buffer(BUFFER_SIZE);
while (file) {
file.read(reinterpret_cast<char*>(buffer.data()), BUFFER_SIZE);
std::streamsize bytesRead = file.gcount();
if (bytesRead > 0) {
status = BCryptHashData(hHash, buffer.data(), static_cast<ULONG>(bytesRead), 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
}
}
std::vector<BYTE> hash(hashLen);
status = BCryptFinishHash(hHash, hash.data(), hashLen, 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return bytesToHex(hash);
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
};
// 4. SHA512 Hash Calculation
class SHA512Hash {
public:
static std::string calculate(const std::string& input) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
NTSTATUS status;
DWORD hashLen = 0;
DWORD resultLen = 0;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA512_ALGORITHM, nullptr, 0);
if (status != 0) {
return "";
}
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, reinterpret_cast<PBYTE>(&hashLen), sizeof(hashLen), &resultLen, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
status = BCryptCreateHash(hAlg, &hHash, nullptr, 0, nullptr, 0, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
status = BCryptHashData(hHash, reinterpret_cast<PBYTE>(const_cast<char*>(input.c_str())), input.size(), 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
std::vector<BYTE> hash(hashLen);
status = BCryptFinishHash(hHash, hash.data(), hashLen, 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return bytesToHex(hash);
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
};
// 5. Compare Hash Values
class HashComparator {
public:
static bool compare(const std::string& hash1, const std::string& hash2) {
// Case-insensitive comparison
if (hash1.length() != hash2.length()) {
return false;
}
for (size_t i = 0; i < hash1.length(); ++i) {
char c1 = tolower(hash1[i]);
char c2 = tolower(hash2[i]);
if (c1 != c2) {
return false;
}
}
return true;
}
static bool verifyFileIntegrity(const std::string& filename, const std::string& expectedHash) {
std::string actualHash = SHA256Hash::calculateFile(filename);
if (actualHash.empty()) {
return false;
}
return compare(actualHash, expectedHash);
}
};
// 6. HMAC (Hash-based Message Authentication Code)
class HMACSHA256 {
public:
static std::string calculate(const std::string& message, const std::string& key) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_HASH_HANDLE hHash = nullptr;
NTSTATUS status;
DWORD hashLen = 0;
DWORD resultLen = 0;
// Open algorithm provider
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, BCRYPT_ALG_HANDLE_HMAC_FLAG);
if (status != 0) {
std::cerr << "Failed to open algorithm provider" << std::endl;
return "";
}
// Create hash with key
status = BCryptCreateHash(hAlg, &hHash, nullptr, 0,
reinterpret_cast<PBYTE>(const_cast<char*>(key.c_str())),
static_cast<ULONG>(key.size()), 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Hash message
status = BCryptHashData(hHash, reinterpret_cast<PBYTE>(const_cast<char*>(message.c_str())),
static_cast<ULONG>(message.size()), 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Get hash length
status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, reinterpret_cast<PBYTE>(&hashLen), sizeof(hashLen), &resultLen, 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
// Get hash value
std::vector<BYTE> hash(hashLen);
status = BCryptFinishHash(hHash, hash.data(), hashLen, 0);
if (status != 0) {
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return "";
}
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return bytesToHex(hash);
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
};
// Main demonstration
int main() {
std::cout << "=== Windows C++ Hash Calculation Examples ===" << std::endl;
std::string testString = "Hello, World!";
std::cout << "Input string: " << testString << std::endl;
// 1. MD5
std::cout << "\n--- MD5 Hash ---" << std::endl;
std::string md5Hash = MD5Hash::calculate(testString);
std::cout << "MD5: " << md5Hash << std::endl;
// 2. SHA1
std::cout << "\n--- SHA1 Hash ---" << std::endl;
std::string sha1Hash = SHA1Hash::calculate(testString);
std::cout << "SHA1: " << sha1Hash << std::endl;
// 3. SHA256
std::cout << "\n--- SHA256 Hash ---" << std::endl;
std::string sha256Hash = SHA256Hash::calculate(testString);
std::cout << "SHA256: " << sha256Hash << std::endl;
// 4. SHA512
std::cout << "\n--- SHA512 Hash ---" << std::endl;
std::string sha512Hash = SHA512Hash::calculate(testString);
std::cout << "SHA512: " << sha512Hash << std::endl;
// 5. File hashing
std::cout << "\n--- File Hashing ---" << std::endl;
// Create test file
std::ofstream testFile("test_file.txt");
testFile << "This is a test file for hash calculation.";
testFile.close();
std::string fileMD5 = MD5Hash::calculateFile("test_file.txt");
std::cout << "File MD5: " << fileMD5 << std::endl;
std::string fileSHA256 = SHA256Hash::calculateFile("test_file.txt");
std::cout << "File SHA256: " << fileSHA256 << std::endl;
// 6. Hash comparison
std::cout << "\n--- Hash Comparison ---" << std::endl;
std::string hash1 = "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146";
std::string hash2 = "A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146";
bool match = HashComparator::compare(hash1, hash2);
std::cout << "Hash comparison (case insensitive): " << (match ? "MATCH" : "NO MATCH") << std::endl;
// Verify file integrity
bool integrity = HashComparator::verifyFileIntegrity("test_file.txt", fileSHA256);
std::cout << "File integrity check: " << (integrity ? "PASSED" : "FAILED") << std::endl;
// 7. HMAC
std::cout << "\n--- HMAC-SHA256 ---" << std::endl;
std::string message = "Important message to authenticate";
std::string key = "secret_key_123";
std::string hmac = HMACSHA256::calculate(message, key);
std::cout << "Message: " << message << std::endl;
std::cout << "Key: " << key << std::endl;
std::cout << "HMAC-SHA256: " << hmac << std::endl;
std::cout << "\n=== All Hash Calculation Examples Completed ===" << std::endl;
return 0;
}
💻 Criptografia/Descriptografia AES cpp
🟡 intermediate
⭐⭐⭐⭐
Implementar criptografia e descriptografia AES-256 usando Windows Cryptography API (CNG)
⏱️ 35 min
🏷️ cpp, cryptography, aes, encryption, windows
Prerequisites:
Advanced C++, Windows Cryptography API (CNG)
// Windows C++ AES Encryption/Decryption Examples
// Using Cryptography Next Generation (CNG) API
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib")
// 1. Basic AES-256 Encryption
class AESEncryptor {
private:
BCRYPT_ALG_HANDLE hAlg;
BCRYPT_KEY_HANDLE hKey;
std::vector<BYTE> keyObject;
std::vector<BYTE> iv;
public:
AESEncryptor() : hAlg(nullptr), hKey(nullptr) {}
~AESEncryptor() {
cleanup();
}
bool initialize(const std::vector<BYTE>& key) {
NTSTATUS status;
DWORD resultLen;
// Open algorithm provider (AES-256-CBC)
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, nullptr, 0);
if (status != 0) {
std::cerr << "BCryptOpenAlgorithmProvider failed: " << status << std::endl;
return false;
}
// Set chaining mode to CBC
status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
reinterpret_cast<PBYTE>(const_cast<char*>(BCRYPT_CHAIN_MODE_CBC)),
sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
if (status != 0) {
std::cerr << "BCryptSetProperty failed: " << status << std::endl;
cleanup();
return false;
}
// Get key object length
status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH,
reinterpret_cast<PBYTE>(&resultLen), sizeof(resultLen), &resultLen, 0);
if (status != 0) {
cleanup();
return false;
}
keyObject.resize(resultLen);
// Generate key from key material
status = BCryptGenerateSymmetricKey(hAlg, &hKey,
keyObject.data(), keyObject.size(),
const_cast<PBYTE>(key.data()), key.size(), 0);
if (status != 0) {
std::cerr << "BCryptGenerateSymmetricKey failed: " << status << std::endl;
cleanup();
return false;
}
// Get IV length
status = BCryptGetProperty(hAlg, BCRYPT_BLOCK_LENGTH,
reinterpret_cast<PBYTE>(&resultLen), sizeof(resultLen), &resultLen, 0);
if (status != 0) {
cleanup();
return false;
}
iv.resize(resultLen, 0); // Initialize with zeros
return true;
}
std::vector<BYTE> encrypt(const std::vector<BYTE>& plaintext) {
if (hAlg == nullptr || hKey == nullptr) {
std::cerr << "Encryptor not initialized" << std::endl;
return {};
}
NTSTATUS status;
DWORD resultLen;
// Get ciphertext length
status = BCryptEncrypt(hKey, const_cast<PBYTE>(plaintext.data()),
static_cast<ULONG>(plaintext.size()), nullptr,
iv.data(), iv.size(), nullptr, 0, &resultLen, BCRYPT_BLOCK_PADDING);
if (status != 0) {
std::cerr << "BCryptEncrypt (get size) failed: " << status << std::endl;
return {};
}
std::vector<BYTE> ciphertext(resultLen);
// Encrypt data
status = BCryptEncrypt(hKey, const_cast<PBYTE>(plaintext.data()),
static_cast<ULONG>(plaintext.size()), nullptr,
iv.data(), iv.size(), ciphertext.data(),
static_cast<ULONG>(ciphertext.size()), &resultLen, BCRYPT_BLOCK_PADDING);
if (status != 0) {
std::cerr << "BCryptEncrypt failed: " << status << std::endl;
return {};
}
ciphertext.resize(resultLen);
return ciphertext;
}
std::vector<BYTE> decrypt(const std::vector<BYTE>& ciphertext) {
if (hAlg == nullptr || hKey == nullptr) {
std::cerr << "Encryptor not initialized" << std::endl;
return {};
}
NTSTATUS status;
DWORD resultLen;
// Get plaintext length
status = BCryptDecrypt(hKey, const_cast<PBYTE>(ciphertext.data()),
static_cast<ULONG>(ciphertext.size()), nullptr,
iv.data(), iv.size(), nullptr, 0, &resultLen, BCRYPT_BLOCK_PADDING);
if (status != 0) {
std::cerr << "BCryptDecrypt (get size) failed: " << status << std::endl;
return {};
}
std::vector<BYTE> plaintext(resultLen);
// Decrypt data
status = BCryptDecrypt(hKey, const_cast<PBYTE>(ciphertext.data()),
static_cast<ULONG>(ciphertext.size()), nullptr,
iv.data(), iv.size(), plaintext.data(),
static_cast<ULONG>(plaintext.size()), &resultLen, BCRYPT_BLOCK_PADDING);
if (status != 0) {
std::cerr << "BCryptDecrypt failed: " << status << std::endl;
return {};
}
plaintext.resize(resultLen);
return plaintext;
}
void setIV(const std::vector<BYTE>& newIV) {
iv = newIV;
}
std::vector<BYTE> getIV() const {
return iv;
}
private:
void cleanup() {
if (hKey) {
BCryptDestroyKey(hKey);
hKey = nullptr;
}
if (hAlg) {
BCryptCloseAlgorithmProvider(hAlg, 0);
hAlg = nullptr;
}
}
};
// 2. Generate Random AES Key
class KeyGenerator {
public:
static std::vector<BYTE> generateAESKey(int bits = 256) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
NTSTATUS status;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, nullptr, 0);
if (status != 0) {
std::cerr << "Failed to open RNG provider" << std::endl;
return {};
}
int keyLen = bits / 8;
std::vector<BYTE> key(keyLen);
status = BCryptGenRandom(hAlg, key.data(), keyLen, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return {};
}
BCryptCloseAlgorithmProvider(hAlg, 0);
return key;
}
static std::vector<BYTE> generateIV(int size = 16) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
NTSTATUS status;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM, nullptr, 0);
if (status != 0) {
return {};
}
std::vector<BYTE> iv(size);
status = BCryptGenRandom(hAlg, iv.data(), size, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return {};
}
BCryptCloseAlgorithmProvider(hAlg, 0);
return iv;
}
};
// 3. String Encryption/Decryption Helper
class StringCryptor {
public:
static std::string encryptString(const std::string& plaintext, const std::vector<BYTE>& key) {
// Convert string to byte vector
std::vector<BYTE> data(plaintext.begin(), plaintext.end());
AESEncryptor encryptor;
if (!encryptor.initialize(key)) {
return "";
}
std::vector<BYTE> ciphertext = encryptor.encrypt(data);
// Return as hex string for display
return bytesToHex(ciphertext);
}
static std::string decryptString(const std::string& hexCiphertext, const std::vector<BYTE>& key) {
// Convert hex string to byte vector
std::vector<BYTE> ciphertext = hexToBytes(hexCiphertext);
AESEncryptor encryptor;
if (!encryptor.initialize(key)) {
return "";
}
std::vector<BYTE> plaintext = encryptor.decrypt(ciphertext);
return std::string(plaintext.begin(), plaintext.end());
}
private:
static std::string bytesToHex(const std::vector<BYTE>& bytes) {
std::string hex;
hex.reserve(bytes.size() * 2);
for (BYTE b : bytes) {
char buf[3];
sprintf_s(buf, "%02x", b);
hex += buf;
}
return hex;
}
static std::vector<BYTE> hexToBytes(const std::string& hex) {
std::vector<BYTE> bytes;
for (size_t i = 0; i < hex.length(); i += 2) {
std::string byteString = hex.substr(i, 2);
BYTE byte = static_cast<BYTE>(strtol(byteString.c_str(), nullptr, 16));
bytes.push_back(byte);
}
return bytes;
}
};
// 4. File Encryption/Decryption
class FileCryptor {
public:
static bool encryptFile(const std::string& inputFile, const std::string& outputFile,
const std::vector<BYTE>& key) {
// Read input file
std::ifstream inFile(inputFile, std::ios::binary);
if (!inFile) {
std::cerr << "Failed to open input file" << std::endl;
return false;
}
std::vector<BYTE> plaintext((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
inFile.close();
// Encrypt
AESEncryptor encryptor;
if (!encryptor.initialize(key)) {
return false;
}
std::vector<BYTE> ciphertext = encryptor.encrypt(plaintext);
if (ciphertext.empty()) {
return false;
}
// Write output file
std::ofstream outFile(outputFile, std::ios::binary);
if (!outFile) {
std::cerr << "Failed to open output file" << std::endl;
return false;
}
outFile.write(reinterpret_cast<const char*>(ciphertext.data()), ciphertext.size());
outFile.close();
std::cout << "File encrypted: " << inputFile << " -> " << outputFile << std::endl;
return true;
}
static bool decryptFile(const std::string& inputFile, const std::string& outputFile,
const std::vector<BYTE>& key) {
// Read input file
std::ifstream inFile(inputFile, std::ios::binary);
if (!inFile) {
std::cerr << "Failed to open input file" << std::endl;
return false;
}
std::vector<BYTE> ciphertext((std::istreambuf_iterator<char>(inFile)),
std::istreambuf_iterator<char>());
inFile.close();
// Decrypt
AESEncryptor encryptor;
if (!encryptor.initialize(key)) {
return false;
}
std::vector<BYTE> plaintext = encryptor.decrypt(ciphertext);
if (plaintext.empty()) {
return false;
}
// Write output file
std::ofstream outFile(outputFile, std::ios::binary);
if (!outFile) {
std::cerr << "Failed to open output file" << std::endl;
return false;
}
outFile.write(reinterpret_cast<const char*>(plaintext.data()), plaintext.size());
outFile.close();
std::cout << "File decrypted: " << inputFile << " -> " << outputFile << std::endl;
return true;
}
};
// 5. AES-GCM (Galois/Counter Mode) - Authenticated Encryption
class AESGCM {
public:
struct GCMResult {
std::vector<BYTE> ciphertext;
std::vector<BYTE> tag;
};
static GCMResult encrypt(const std::vector<BYTE>& plaintext, const std::vector<BYTE>& key,
const std::vector<BYTE>& iv, const std::vector<BYTE>& aad = {}) {
GCMResult result;
BCRYPT_ALG_HANDLE hAlg = nullptr;
BCRYPT_KEY_HANDLE hKey = nullptr;
NTSTATUS status;
// Open AES provider
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_AES_ALGORITHM, nullptr, 0);
if (status != 0) {
return result;
}
// Set GCM mode
status = BCryptSetProperty(hAlg, BCRYPT_CHAINING_MODE,
reinterpret_cast<PBYTE>(const_cast<char*>(BCRYPT_CHAIN_MODE_GCM)),
sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return result;
}
// Create key
std::vector<BYTE> keyObj;
DWORD keyObjLen;
BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH,
reinterpret_cast<PBYTE>(&keyObjLen), sizeof(keyObjLen), &keyObjLen, 0);
keyObj.resize(keyObjLen);
status = BCryptGenerateSymmetricKey(hAlg, &hKey,
keyObj.data(), keyObj.size(),
const_cast<PBYTE>(key.data()), key.size(), 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return result;
}
// Get tag length
DWORD tagLen = 16;
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO authInfo = {0};
authInfo.pbNonce = const_cast<PBYTE>(iv.data());
authInfo.cbNonce = iv.size();
authInfo.pbAuthData = const_cast<PBYTE>(aad.data());
authInfo.cbAuthData = aad.size();
authInfo.pbTag = result.tag.data();
authInfo.cbTag = tagLen;
result.tag.resize(tagLen);
// Get output length
DWORD ciphertextLen;
status = BCryptEncrypt(hKey, const_cast<PBYTE>(plaintext.data()), plaintext.size(),
&authInfo, nullptr, 0, nullptr, 0, &ciphertextLen, 0);
if (status != 0) {
BCryptDestroyKey(hKey);
BCryptCloseAlgorithmProvider(hAlg, 0);
return result;
}
result.ciphertext.resize(ciphertextLen);
// Encrypt
status = BCryptEncrypt(hKey, const_cast<PBYTE>(plaintext.data()), plaintext.size(),
&authInfo, nullptr, 0, result.ciphertext.data(), ciphertextLen, &ciphertextLen, 0);
result.ciphertext.resize(ciphertextLen);
BCryptDestroyKey(hKey);
BCryptCloseAlgorithmProvider(hAlg, 0);
return result;
}
};
// 6. Password-Based Key Derivation (PBKDF2)
class PasswordKeyDerivation {
public:
static std::vector<BYTE> deriveKey(const std::string& password, const std::vector<BYTE>& salt,
int iterations = 10000, int keyLen = 32) {
BCRYPT_ALG_HANDLE hAlg = nullptr;
NTSTATUS status;
status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, nullptr, 0);
if (status != 0) {
return {};
}
// Create hash for password
BCRYPT_HASH_HANDLE hHash = nullptr;
std::vector<BYTE> hashObj;
DWORD hashObjLen;
BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH,
reinterpret_cast<PBYTE>(&hashObjLen), sizeof(hashObjLen), &hashObjLen, 0);
hashObj.resize(hashObjLen);
status = BCryptCreateHash(hAlg, &hHash, hashObj.data(), hashObjLen,
nullptr, 0, 0);
if (status != 0) {
BCryptCloseAlgorithmProvider(hAlg, 0);
return {};
}
// Simple key derivation (in production, use proper KDF like BCryptDeriveKeyPBKDF2)
std::vector<BYTE> key(keyLen);
std::vector<BYTE> passwordBytes(password.begin(), password.end());
// Combine password + salt and hash
std::vector<BYTE> combined = passwordBytes;
combined.insert(combined.end(), salt.begin(), salt.end());
for (int i = 0; i < iterations; i++) {
BCryptHashData(hHash, combined.data(), combined.size(), 0);
DWORD hashLen = 32;
std::vector<BYTE> hash(32);
BCryptFinishHash(hHash, hash.data(), hashLen, 0);
if (i == iterations - 1) {
// Use final hash as key
std::copy(hash.begin(), hash.begin() + std::min(keyLen, 32), key.begin());
}
// Use hash as input for next iteration
combined = hash;
}
BCryptDestroyHash(hHash);
BCryptCloseAlgorithmProvider(hAlg, 0);
return key;
}
};
// Main demonstration
int main() {
std::cout << "=== Windows C++ AES Encryption/Decryption Examples ===" << std::endl;
// 1. Generate random key
std::cout << "\n--- Key Generation ---" << std::endl;
std::vector<BYTE> key = KeyGenerator::generateAESKey(256);
std::cout << "Generated AES-256 Key: ";
for (BYTE b : key) {
printf("%02x", b);
}
std::cout << std::endl;
std::vector<BYTE> iv = KeyGenerator::generateIV(16);
std::cout << "Generated IV: ";
for (BYTE b : iv) {
printf("%02x", b);
}
std::cout << std::endl;
// 2. String encryption/decryption
std::cout << "\n--- String Encryption ---" << std::endl;
std::string plaintext = "Hello, World! This is a secret message.";
std::cout << "Original: " << plaintext << std::endl;
std::string encryptedHex = StringCryptor::encryptString(plaintext, key);
std::cout << "Encrypted: " << encryptedHex << std::endl;
std::string decrypted = StringCryptor::decryptString(encryptedHex, key);
std::cout << "Decrypted: " << decrypted << std::endl;
// 3. File encryption/decryption
std::cout << "\n--- File Encryption ---" << std::endl;
std::ofstream testFile("plain_file.txt");
testFile << "This is the content of a secret file.";
testFile.close();
FileCryptor::encryptFile("plain_file.txt", "encrypted_file.bin", key);
FileCryptor::decryptFile("encrypted_file.bin", "decrypted_file.txt", key);
// 4. Password-based key derivation
std::cout << "\n--- Password Key Derivation ---" << std::endl;
std::string password = "mySecurePassword123";
std::vector<BYTE> salt = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
std::vector<BYTE> derivedKey = PasswordKeyDerivation::deriveKey(password, salt, 10000, 32);
std::cout << "Password: " << password << std::endl;
std::cout << "Derived Key: ";
for (BYTE b : derivedKey) {
printf("%02x", b);
}
std::cout << std::endl;
std::cout << "\n=== All AES Encryption Examples Completed ===" << std::endl;
return 0;
}