English 中文(简体)
我的法典为什么在加密给AES 256之后被hang?
原标题:Why does my code hang after encrypting to AES 256?

我已根据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;
}
问题回答

这里至少有一个错误:

你这样做:

pbPlainText = (PBYTE)inputString.c_str();

然后在<代码>Cleanup上,请:

if (pbPlainText){
     HeapFree(GetProcessHeap(), 0, pbPlainText);
}

很显然,<代码>pbPlainText没有分配到HeapAlloc,但请上。 HeapFree using pbPlainText.

定本是删除<条码>免费

此外,这种情况永远不会发生:

pbPlainText = (PBYTE)inputString.c_str();
        if (pbPlainText == NULL){

<代码>c_str(>的价值始终是一个有效的点。 它指出什么可能是空的,即pbPlainText.empty() 回归代码,但它永远不会是NUL。

此外,最好写一下,该守则的整个清理部分是使用RAII,以便不仅能够删除goto 游戏,而且将保证无论何时恢复记忆。 如果出于某种原因,守则中将出现例外,这一点非常重要,而且你需要确保释放记忆。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签