我已根据AES 256算法撰写了加密法,并努力给我一个产出档案,但我相信,该编码在运行加密功能后会hang,此后不会做任何其他事情。 为什么如此? 我如何进一步改进这一守则,以进行加密和加密?
#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#include <iostream>
#include <fstream>
#include <string>
#pragma comment(lib, "bcrypt.lib")
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
// Function to decrypt using AES256 algorithm
void ENcryptDecryptString(const std::string& inputString, const std::string& outputFile, bool encrypt){
// Constants for encryption
#define KEY_SIZE 32
#define IV_SIZE 16
const unsigned char ENCRYPTION_KEY[KEY_SIZE] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0xoF,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};
const unsigned char IV[IV_SIZE] = {
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
};
BCRYPT_ALG_HANDLE hAesAlg = NULL;
BCRYPT_KEY_HANDLE hKey = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
DWORD cbCipherText = 0, cbPlainText = 0, cbData = 0, cbKeyObject = 0, cbBlockLen = 0, cbBlob = 0;
PBYTE pbCipherText = NULL, pbPlainText = NULL, pbKeyObject = NULL, pbIV = NULL, pbBlob = NULL;
// Open an algorithm handle
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0))){
wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider
", status);
goto Cleanup;
}
// Calculate the size of the buffer to hold the KeyObject
if (!NT_SUCCESS(status = BCryptGetProperty(hAesAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbKeyObject, sizeof(DWORD), &cbData, 0))){
wprintf(L"**** Error 0x%x returned by BCryptGetProperty
", status);
goto Cleanup;
}
// Allocate the key object on the heap
pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
if (pbKeyObject == NULL){
wprintf(L"**** memory allocation failed
");
goto Cleanup;
}
// Calculate the block length for the IV
if (!NT_SUCCESS(status = BCryptGetProperty(hAesAlg, BCRYPT_BLOCK_LENGTH, (PBYTE)&cbBlockLen, sizeof(DWORD), &cbData, 0))){
wprintf(L"**** Error 0x%x returned by BCryptGetProperty_IV
", status);
goto Cleanup;
}
// Allocate a buffer for the IV
pbIV = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlockLen);
if (pbIV == NULL){
wprintf(L"**** IV memory allocation failed
");
goto Cleanup;
}
// Use the provided IV
memcpy(pbIV, IV, IV_SIZE);
// Set the chaining mode to CBC
if (!NT_SUCCESS(status = BCryptSetProperty(hAesAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0))){
wprintf(L"**** Error 0x%x returned by BCryptGetProperty_chaining_mode
", status);
goto Cleanup;
}
// Generate the key from supplied input key bytes
if (!NT_SUCCESS(status = BCryptGenerateSymmetricKey(hAesAlg, &hKey, pbKeyObject, cbKeyObject, (PBYTE)ENCRYPTION_KEY, KEY_SIZE, 0))){
wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey
", status);
goto Cleanup;
}
// Allocate memory for the plaintext or ciphertext buffercbData = inputString.length();
if (encrypt){
pbPlainText = (PBYTE)inputString.c_str();
cbPlainText = cbData;
// Get the size of the encrypted outputFile
if (!NT_SUCCESS(status = BCryptEncrypt(hKey, pbPlainText, cbPlainText, NULL, pbIV, cbBlockLen, NULL, 0, &cbCipherText, BCRYPT_BLOCK_PADDING))){
wprintf(L"**** Error 0x%x returned by BCryptEncrypt
", status);
goto Cleanup;
}
pbCipherText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbCipherText);
if (pbCipherText == NULL){
wprintf(L"**** memory allocation failed_pbCipherText
");
goto Cleanup;
}
// Perform encryption
if (!NT_SUCCESS(status = BCryptEncrypt(hKey, pbPlainText, cbPlainText, NULL, pbIV, cbBlockLen, pbCipherText, cbCipherText, &cbData, BCRYPT_BLOCK_PADDING))){
wprintf(L"**** Error 0x%x returned by BCryptEncrypt_encryption
", status);
goto Cleanup;
}
// Write the encrypted data to the output filebuf
std::ofstream ofs(outputFile, std::ios::binary);
if (!ifs){
std::cerr << "Error: Failed to open input file." << std::endl;
goto Cleanup;
}
ofs.write(reinterpret_cast<char*>(pbCipherText), cbCipherText);
} else {
// Decrypting
std::ifstream ifs(inputString, std::ios::binary);
if(!ifs){
std::cerr << "Error: Failed to open input file." << std::endl;
goto Cleanup;
}
// Get the size of the file
ifs.seekg(0, std::ios::end);
std::streampos fileSize = ifs.tellg();
ifs.seekg(0, std::ios::beg);
// Read the file content into the buffer
pbCipherText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, fileSize);
if (pbCipherText == NULL){
wprintf(L"**** memory allocation failed_pbCipherText
");
goto Cleanup;
}
ifs.read(reinterpret_cast<char*>(pbCipherText), fileSize);
cbCipherText = static_cast<DWORD>(fileSize);
// Decrypt the data
if (!NT_SUCCESS(status = BCryptDecrypt(hKey, pbCipherText, cbCipherText, NULL, pbIV, cbBlockLen, NULL, 0, &cbPlainText, BCRYPT_BLOCK_PADDING))){
wprintf(L"**** Error 0x%x returned by BCryptDecrypt
", status);
goto Cleanup;
}
pbPlainText = (PBYTE)inputString.c_str();
if (pbPlainText == NULL){
wprintf(L"**** memory allocation failed_pbPlainText
");
goto Cleanup;
}
// Perform decryption
if (!NT_SUCCESS(status = BCryptDecrypt(hKey, pbCipherText, cbCipherText, NULL, pbIV, cbBlockLen, pbPlainText, cbPlainText, &cbData, BCRYPT_BLOCK_PADDING))){
wprintf(L"**** Error 0x%x returned by BCryptDecrypt_decryption
", status);
goto Cleanup;
}
// Determine the padding length
BYTE paddingLength = pbPlainText[cbPlainText - 1];
// Remove the padding from the plaintext
cbPlainText -= paddingLength;
// Write the decrypted data to the output file
std::ofstream ofs(outputFile, std::ios::binary);
if (!ofs){
std::cerr << "Error: Failed to open output file." << std::endl;
goto Cleanup;
}
ofs.write(reinterpret_cast<char*>(pbPlainText), cbPlainText);
}
Cleanup:
if (pbCipherText){
HeapFree(GetProcessHeap(), 0, pbCipherText);
}
if (pbPlainText){
HeapFree(GetProcessHeap(), 0, pbPlainText);
}
if (pbKeyObject){
HeapFree(GetProcessHeap(), 0, pbKeyObject);
}
if (pbIV){
HeapFree(GetProcessHeap(), 0, pbIV);
}
if (hKey){
BCryptDestroyKey(hKey);
}
if (hAesAlg){
BCryptCloseAlgorithmProvider(hAesAlg, 0);
}
}
int main(int argc, char* argv[])
{
if (argc != 3){
std::cerr << "Usage: " << argv[0] << " <plain_string> <output_file>" << std::endl;
return 1;
}
std::string inputString = argv[1];
std::string outputFile = argv[2];
EncryptDecryptString(inputString, outputFile, true);
std::cerr << "Encryption successful." << std::endl;
return 0;
}