Bcryptdecrypt unable to decrypt data correctly

Ritu Varkey 41 Reputation points
2023-05-10T06:55:40.8566667+00:00

I have some data that was previously encrtypted with cryptdecrypt APIs. Since it is deprecated I am supposed to move to the latest bcryptdecrypt (CNG)APIs. But with this code I am not able to decrypt the data correctly. I still see junk in pbPlainText.The APIs are all successful only the decryption is not happening correctly. This is the code:


bool decrypt(PBYTE pbCipherText,DWORD cbCipherText)
{
   BCRYPT_KEY_HANDLE hKey = NULL;
   BCRYPT_ALG_HANDLE  m_Context;
   NTSTATUS status = 0;
    DWORD cbBlockLen = 0;
    DWORD cbKeyObject = 0;
    DWORD cbData = 0;
    // Set up the initial vector
    PBYTE pbIV = nullptr;
    PBYTE pbKeyObject = nullptr;

    bool ret = false;

if (BCryptOpenAlgorithmProvider(
        &m_Context,
        BCRYPT_AES_ALGORITHM,
        NULL,
        0))
    {
        Result = FALSE;
        throw exLibCryptoException("Unable to find CryptAcquireContext function");

    } 

    if (status=BCryptGetProperty(
        m_Context,
        BCRYPT_OBJECT_LENGTH,
        (PBYTE)&cbKeyObject,
        sizeof(DWORD),
        &cbData,
        0))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
    }

    // Allocate the key object on the heap.
    pbKeyObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbKeyObject);
    if (NULL == pbKeyObject)
    {
        wprintf(L"**** memory allocation failed\n");

    }
    
    // Generate the key from supplied input key bytes.
    if (!NT_SUCCESS(status = BCryptGenerateSymmetricKey(
        m_Context,
        &hKey,//,nullptr, 0,
        pbKeyObject,
        cbKeyObject,
        KeyData,
        KeySize,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\n", status);

    }



    // Save another copy of the key for later.
    if (!NT_SUCCESS(status = BCryptExportKey(
        hKey,
        NULL,
        BCRYPT_OPAQUE_KEY_BLOB,
        NULL,
        0,
        &cbBlob,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptExportKey\n", status);

    }


    // Allocate the buffer to hold the BLOB.
    pbBlob = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlob);
    if (NULL == pbBlob)
    {
        //EM_LOG_TRIVIAL_A("**** memory allocation failed\n");

    }

    if (!NT_SUCCESS(status = BCryptExportKey(
        hKey,
        NULL,
        BCRYPT_OPAQUE_KEY_BLOB,
        pbBlob,
        cbBlob,
        &cbBlob,
        0)))
    {
        //EM_LOG_TRIVIAL_2(L"**** Error 0x%x returned by BCryptExportKey\n", status);

    }

    status = BCryptImportKey(m_Context, nullptr, BCRYPT_OPAQUE_KEY_BLOB, &hKey, pbKeyObject,
        cbKeyObject, pbBlob, cbBlob, 0);



    if (!NT_SUCCESS(status = BCryptGetProperty(
        m_Context,
        BCRYPT_BLOCK_LENGTH,
        (PBYTE)&cbBlockLen,
        sizeof(DWORD),
        &cbData,
        0)))
    {
        //EM_LOG_TRIVIAL_2(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
        ret = false;
    }
    
    pbIV = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbBlockLen);
    if (NULL == pbIV)
    {
        ///EM_LOG_TRIVIAL_2(L"**** memory allocation failed\n");
        ret = false;
    }

    if (!NT_SUCCESS(status = BCryptGenRandom(BCRYPT_RNG_ALG_HANDLE, pbIV, cbBlockLen, 0)))
    {
        goto Cleanup;
    }


    if (!NT_SUCCESS(status = BCryptSetProperty(
        m_Context,
        BCRYPT_CHAINING_MODE,
        (PBYTE)BCRYPT_CHAIN_MODE_CBC,
        sizeof(BCRYPT_CHAIN_MODE_CBC),
        0)))
    {
        //wprintf(L"**** Error 0x%x returned by BCryptSetProperty\n", status);
    }
    

    if (_Data.size() < cbBlockLen)
        return false;

    
        //check that size is multiple of 16
        if (cbCipherText % 16) {
            return false;
        }

        if (!NT_SUCCESS(status = BCryptDecrypt(
            hKey,
            pbCipherText,
            cbCipherText,
            NULL,
            pbIV,
            cbBlockLen,
            NULL,
            0,
            &cbPlainText,
            0)))
        {
            wprintf(L"**** Error 0x%x returned by BCryptDecrypt\n", status);
        }


        pbPlainText = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbPlainText);
        if (NULL == pbPlainText)
        {
            //wprintf(L"**** memory allocation failed\n");
        }

        if (!NT_SUCCESS(status = BCryptDecrypt(
            hKey,
            pbCipherText,
            cbCipherText,
            NULL,
            pbIV,
            cbBlockLen,
            pbPlainText,
            cbPlainText,
            &cbPlainText,
            0)))
        {
            wprinft("decrypt failed");
        }
        

    return true;
}
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,516 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,631 questions
Windows 11
Windows 11
A Microsoft operating system designed for productivity, creativity, and ease of use.
8,959 questions
0 comments No comments
{count} votes

Accepted answer
  1. Jeanine Zhang-MSFT 9,431 Reputation points Microsoft Vendor
    2023-05-10T08:53:36.3366667+00:00

    Hello,

    Welcome to Microsoft Q&A!

    It seems that you couldn't free a memory block allocated from a heap by the HeapAlloc.

    pbIV: The address of a buffer that contains the initialization vector (IV) to use during decryption.

    As far as I'm concerned, IV already exists, you should not generate it by BCryptGenRandom.

    And I suggest you could refer to the Doc: Encrypting Data with CNG

    Thank you.

    Jeanine


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.

    1 deleted comment

    Comments have been turned off. Learn more

  2. kwikc 131 Reputation points
    2023-05-10T13:24:22.26+00:00

    If that is a word for word copy, I think the forum should have a mechanism to stop shameless posting like that.