2014-09-01 92 views
1

如何使用Microsoft CryptoAPI(CryptDeriveKey,BCrypt函數,CryptAcquireContext等)將以下加密代碼(VB.NET 4.0)轉換爲與C++等價的代碼? (我還沒有在網上查到描述使用Microsoft CryptoAPI的AES在單篇文章......)C++中的AES/Rijndael 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

如果您不介意,我們希望您嘗試一下自己,如果您遇到困難,請回來。 – 2014-09-01 17:41:38

+0

開始閱讀[這裏](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380256(v = vs.85).aspx),然後編寫一些代碼,看看會發生什麼。 – 2014-09-01 17:53:23

+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-辦法對隱窩-A-文件與-CNG))。那麼,我能做些什麼來解決所有上述問題? (放棄XP平臺不是我的選擇...) – Jason 2014-09-02 10:13:23

回答

2

所以,代碼爲我AES-256加密/解密是由以下內容:(它需要BYTE* DataBYTE* 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代碼的每個人都有用。