2010-01-28 1729 views
3


我試圖解密之前用C#TripleDESCryptoServiceProvider加密的非託管C++中的文件。不幸的是,我不知道如何使用Microsoft Crypt API(advapi32.lib)來做到這一點。下面是我用來加密數據的C#代碼:在C++中使用用Crypt API加密的C++中的TripleDES解密文件

private static void EncryptData(MemoryStream streamToEncrypt) 
    { 
     // initialize the encryption algorithm 
     TripleDES algorithm = new TripleDESCryptoServiceProvider(); 

     byte[] desIV = new byte[8]; 
     byte[] desKey = new byte[16]; 

     for (int i = 0; i < 8; ++i) 
     { 
      desIV[i] = (byte)i; 
     } 

     for (int j = 0; j < 16; ++j) 
     { 
      desKey[j] = (byte)j; 
     } 

     FileStream outputStream = new FileStream(TheCryptedSettingsFilePath, FileMode.OpenOrCreate, FileAccess.Write); 
     outputStream.SetLength(0); 

     CryptoStream encStream = new CryptoStream(outputStream, algorithm.CreateEncryptor(desKey, desIV), 
      CryptoStreamMode.Write); 

     // write the encrypted data to the file 
     encStream.Write(streamToEncrypt.ToArray(), 0, (int)streamToEncrypt.Length); 

     encStream.Close(); 
     outputStream.Close(); 
    } 

正如你所看到的密鑰和IV是相當簡單的(只是用於測試目的)。所以我的問題是,如何在C++中解密該文件?我知道TripleDESCryptoServiceProvider只是Crypt API的包裝器,所以解決這個問題不是那麼困難。
有沒有人做過這樣的事情,可以幫助我?
Thx Simon

+0

你可以使用C++ w/.net運行時? (我敢打賭不,你很可能使用C++,所以你不需要在你的解密應用程序上安裝.net) – 2010-01-29 21:16:46

回答

2

一旦你深入瞭解事情,CryptoAPI使用起來相對簡單。問題是以與其他加密庫(包括.NET框架)兼容的方式進行。我以前成功完成了這個任務,但這已經有一段時間了。主要問題在於如何將純文本密鑰轉換爲可與CryptoAPI一起使用的格式(使用「密鑰塊」進行操作)。幸運的是微軟給了我們a working, if tedious, example。至於CryptoAPI的處事方式,下面是一個例子:

// 1. acquire a provider context. 
// the Microsoft Enhanced provider offers the Triple DES algorithm. 
HCRYPTPROV hProv = NULL; 
if(CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) 
{ 
    // 2. generate the key; see Microsoft KB link above on how to do this. 
    HKEY hKey = NULL; 
    if(ImportPlainTextSessionKey(hProv, lpKeyData, cbKeyData, CALG_3DES, &hKey)) 
    { 
     // 3. set the IV. 
     if(CryptSetKeyParam(hKey, KP_IV, lpIVData, 0)) 
     { 
      // 4. read the encrypted data from the source file. 
      DWORD cbRead = 0; 
      while(ReadFile(hSourceFile, buffer, 8192, &cbRead, NULL) && cbRead) 
      { 
       // 5. decrypt the data (in-place). 
       BOOL bFinal = cbRead < 8192 ? TRUE : FALSE; 
       DWORD cbDecrypted = 0; 
       if(CryptDecrypt(hKey, NULL, bFinal, 0, buffer, &cbDecrypted)) 
       { 
        // 6. write the decrypted data to the destination file. 
        DWORD cbWritten = 0; 
        WriteFile(hDestFile, buffer, cbDecrypted, &cbWritten, NULL); 
       } 
      } 
     } 
     CryptDestroyKey(hKey); 
     hKey = NULL; 
    } 
    CryptReleaseContext(hProv, 0); 
    hProv = NULL; 
} 
+0

非常感謝!你的代碼做到了訣竅。我只需要將鏈接中的代碼與ImportPlainTextSessionKey方法結合起來就可以了。 – 2010-02-04 13:13:51

2

不幸的是,非託管CAPI(advapi32.lib)需要分配比System.Security.Cryptography命名空間更多的代碼。 MSDN有一個名爲「Decrypting a File」的CAPI示例,該示例顯示了在測試應用程序中實現所要執行的所有步驟和調用。這對你來說可能是一個很好的啓動點。對不起,沒有發佈可用的代碼來玩,但當你看看示例代碼,你會看到爲什麼。

+0

這正是問題所在......這是很多代碼,很難因爲這個例子使用了另一種算法。所以覆蓋我的問題的任何代碼片段都會有所幫助。 – 2010-02-03 13:27:48

0

如果您不能使用C中的.NET運行時++中的C一個快速谷歌搜索止跌回升this crypto library ++從我第一glanceover它不依賴於平臺,所以你可以運行此而無需調用advapi32.lib

+0

好吧,我也試過這個庫沒有成功,這裏的一些代碼: ... //讀取文件 fread(buf,len,1,fp); ... BYTE pIV [] = {0,1,2,3,4,5,6,7}; BYTE pKey [] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; const BYTE * lpData =(const BYTE *)(LPCTSTR)buf; size_t bufferSize = strlen(buf); BYTE * result =(BYTE *)malloc(bufferSize); CFB_FIPS_Mode :: Decryption decryption_DES_EDE2_CFB; decryption_DES_EDE2_CFB.SetKeyWithIV(pKey,sizeof(pKey),pIV,sizeof(pIV)); decryption_DES_EDE2_CFB.ProcessString(result,lpData,bufferSize); – 2010-02-03 13:24:48

相關問題