2014-09-01 9 views
1

Как преобразовать следующий криптографический код (VB.NET 4.0) в эквивалент C++, используя функции Microsoft CryptoAPI (CryptDeriveKey, BCrypt [...], CryptAcquireContext и т. Д.)? (Я не нашел ни одной статьи в Интернете, описывающего AES с использованием Microsoft CryptoAPI ...)AES/Rijndael в C++ 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 

и расшифровке один:

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 

(Примечание: У меня уже есть C++ код Коротко о компании . метод SHA-512, так что не беспокойтесь, что)

+3

Если вы не против, мы хотели бы, чтобы вы попробовали себя, вернитесь, если вы где-нибудь застряли. –

+0

Начать чтение [здесь] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa380256 (v = vs.85) .aspx), затем написать код и посмотреть, что произойдет. –

+0

@owlstead Я нашел, как использовать CNG BCrypt.dll, но: 1) Он не поддерживает Windows XP, который имеет вышеуказанный код .NET, 2) Он не поддерживает настраиваемые ключевые/iv длины (свойства BCRYPT_OBJECT_LENGTH и BCRYPT_BLOCK_LENGTH доступны только для чтения) и 3) Он не поддерживает установку настраиваемого ключа из массива байтов (я предполагаю, что, поскольку я читаю [этот код] (http://www.codeproject.com/Articles/18713/Simple- путь к крипте-а-файл-с-CNG)). Итак, что я могу сделать для решения всех вышеперечисленных проблем? (отказ от платформы XP НЕ является для меня опцией ...) – Jason

ответ

2

таким образом, код, который я сделал для AES-256 шифрование/дешифрование является следующее: (он принимает BYTE* Data и BYTE* IV в качестве параметров)

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

Как я уже говорил, у меня уже есть код для функции ComputeSHA512Hash(), поэтому мой код завершен для моих целей. Надеюсь, этот код будет полезен для всех, кто хочет написать AES-256.