使用C#中使用TripleDES加密的Microsoft Crypt API在C ++中解密文件

时间:2010-01-28 15:36:29

标签: c# c++ encryption


我正在尝试解密之前使用C#TripleDESCryptoServiceProvider加密的非托管C ++中的文件。不幸的是,我不知道如何使用Microsoft Crypt API(advapi32.lib)来做到这一点。这是我用来加密数据的C#代码:

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

正如您所看到的,Key和IV非常简单(仅用于测试目的)。所以我的问题是,如何在C ++中解密该文件?我知道TripleDESCryptoServiceProvider只是Crypt API的包装器,因此解决这个问题并不困难。
有没有人做过这样的事情并且可以帮助我?
Thx Simon

3 个答案:

答案 0 :(得分:2)

不幸的是,非托管CAPI(advapi32.lib)需要分配比System.Security.Cryptography命名空间更多的代码。 MSDN有一个名为“Decrypting a File”的CAPI示例,它显示了在测试应用中尝试实现所需的所有步骤和调用。对你来说这可能是一个很好的启动点。很抱歉没有发布可用的代码,但是当您查看示例代码时,您会看到原因。

答案 1 :(得分:2)

一旦你深入了解,CryptoAPI使用相对简单。问题是以与其他加密库(包括.NET框架)兼容的方式进行。我以前成功地做过这件事,但已经有一段时间了;主要的关键点是弄清楚如何将纯文本密钥转换为可与CryptoAPI一起使用的格式(使用“密钥blob”进行操作)。幸运的是,微软给了我们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;
}

答案 2 :(得分:0)

如果你不能在C ++中使用.net运行时从我的第一眼看到的快速谷歌搜索{C} + {+ 3}}它不依赖于平台,所以你可以运行它而无需调用advapi32.lib