Search code examples
c++vb.netencryptioncryptoapimscapi

AES/Rijndael in C++ Microsoft CryptoAPI


How can I convert the following cryptography code (VB.NET 4.0) to the C++ equivalent one, using Microsoft CryptoAPI (CryptDeriveKey, BCrypt[...] functions, CryptAcquireContext, etc.)? (I haven't found a single article on the Internet describing AES using Microsoft CryptoAPI...)

Dim Key(31) As Byte
Dim IV(15) As Byte

Array.Copy(SomeByteArray, IV, 16)
Array.Copy((New SHA512Managed).ComputeHash(SomeByteArray), Key, 32)

Using AESEncr As New RijndaelManaged() With {.Padding = PaddingMode.ISO10126}

    FinalEncrypted = AESEncr.CreateEncryptor(Key, IV).TransformFinalBlock(AnotherByteArray, 0, AnotherByteArray.GetLength(0))

End Using

and the decrypting one:

Dim Key(31) As Byte
Dim IV(15) As Byte

Array.Copy(SomeByteArray, IV, 16)
Array.Copy((New SHA512Managed).ComputeHash(SomeByteArray), Key, 32)

Using AESEncr As New RijndaelManaged() With {.Padding = PaddingMode.ISO10126}

    FinalDecrypted = AESEncr.CreateDecryptor(Key, IV).TransformFinalBlock(FinalEncrypted, 0, FinalEncrypted.GetLength(0))

End Using

(Note: I already have C++ code about the SHA-512 method, so don't bother with that.)


Solution

  • So, the code I made for AES-256 Encryption/Decryption is the following: (it takes BYTE* Data and BYTE* IV as parameters)

        BYTE *hash, *res;
        HCRYPTPROV hCrypt = NULL;
        HCRYPTKEY hKey = NULL;
    
        struct {
            BLOBHEADER hdr;
            DWORD len;
            BYTE key[32];
        } key_blob;
    
        key_blob.hdr.bType = PLAINTEXTKEYBLOB;
        key_blob.hdr.bVersion = CUR_BLOB_VERSION;
        key_blob.hdr.reserved = 0;
        key_blob.hdr.aiKeyAlg = CALG_AES_256;
        key_blob.len = 32;
    
        hash = ComputeSHA512Hash(IV);
        copy(hash, hash + 32, key_blob.key);
    
        res = new BYTE[16];
        copy(Data, Data + 15, res);
        res[15] = 0;
    
        // Get the Microsoft Enhanced RSA and AES Cryptographic Service Provider
    
        if (!CryptAcquireContext(&hCrypt, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
            throw E_FAIL;
    
        // Import our key blob
    
        if (!CryptImportKey(hCrypt, (BYTE *)&key_blob, sizeof(key_blob), NULL, 0, &hKey))
            throw E_FAIL;
    
        // Set the mode to Cipher Block Chaining
    
        DWORD dwMode = CRYPT_MODE_CBC;
    
        if (!CryptSetKeyParam(hKey, KP_MODE, (BYTE *)&dwMode, 0))
            throw E_FAIL;
    
        // Set the Initialization Vector to ours
    
        if (!CryptSetKeyParam(hKey, KP_IV, IV, 0))
            throw E_FAIL;
    
        // Do the main encryption
    
        DWORD pdwDataLen = 15;
    
        if (!CryptEncrypt(hKey, NULL, TRUE, 0, res, &pdwDataLen, 16))
            throw E_FAIL;
    
        // Do the main decryption
    
        pdwDataLen = 16;
    
        if (!CryptDecrypt(hKey, NULL, TRUE, 0, res, &pdwDataLen))
            throw E_FAIL;
    
         // Destroy whatever was created before (free memory)
    
         delete hash;
    
         delete res;
    
         if (hKey)
                CryptDestroyKey(hKey);
    
         if (hCrypt)
                CryptReleaseContext(hCrypt, 0);
    

    As I previously said, I already have code for the ComputeSHA512Hash() function, so my code is complete for my purposes. I hope this code will be useful for everyone wanting to write AES-256 code.