0

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");

    } 

    // Generate the key from supplied input key bytes.
    if (!NT_SUCCESS(status = BCryptGenerateSymmetricKey(
        m_Context,
        &hKey,nullptr, 0,
        KeyData,
        KeySize,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGenerateSymmetricKey\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(L"decrypt failed");
        }
        

    return true;
}

Thanks in Advance!!

RituV
  • 63
  • 1
  • 9
  • Unfortunately the decrypting code is incorrect almost from the begin till the end. Could you reduce and get rid of the irrelevant exports? IV should be given with a ciphertext, but you newly generate it. – 273K May 10 '23 at 07:46
  • I have reduced the code and removed the exports and I'm following this link I found in the microsoft documentation – RituV May 10 '23 at 08:53
  • https://learn.microsoft.com/en-us/windows/win32/seccng/encrypting-data-with-cng – RituV May 10 '23 at 09:51
  • There is no call `BCryptGenRandom` in their example. They use `rgbIV` that is used for encryption. – 273K May 10 '23 at 16:11

1 Answers1

0

I was creating a new IV for decrypting which is wrong. I am supposed to extract the IV and use the buffer without the IV. After doing that it is decrypting fine. Thank You @273K

RituV
  • 63
  • 1
  • 9