2010-01-28 1732 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

相关问题