代码之家  ›  专栏  ›  技术社区  ›  Simon Linder

C++中用TripleDES加密的C++加密文件解密C++中的文件

  •  3
  • Simon Linder  · 技术社区  · 15 年前


    我试图解密一个非托管C++中的文件,该文件以前用C.TyPrPultCythOraceVeServices提供加密。不幸的是,我不知道如何使用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();
        }
    

    正如您所看到的,密钥和IV非常简单(仅用于测试目的)。所以我的问题是,我如何解密C++中的文件?我知道TripleDescryptoServiceProvider只是一个Crypt API的包装器,所以解决这个问题不会那么困难。
    有没有人做过这样的事,可以帮助我?
    西蒙

    3 回复  |  直到 15 年前
        1
  •  2
  •   Luke    15 年前

    一旦你进入事物的最佳状态,CryptoAPI的使用就相对简单了。问题在于这样做的方式与其他加密库(包括.NET框架)兼容。我以前已经成功地完成了这项工作,但是已经有一段时间了;主要的症结在于如何将纯文本密钥转换为可用于CryptoAPI的格式(它与“密钥blobs”一起工作)。幸好微软给了我们 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
  •  2
  •   Mathew Leger    15 年前

    不幸的是,非托管的capi(advapi32.lib)需要分配的代码比可以使用System.Security.Cryptography命名空间执行的代码多。msdn有一个名为__的capi示例 Decrypting a File _它显示了实现您在测试应用程序中尝试执行的操作所需的所有步骤和调用。这可能是一个很好的发射点。很抱歉没有发布可用的代码来播放,但是当您查看示例代码时,您会发现原因。

        3
  •  0
  •   Scott Chamberlain    15 年前

    如果不能在C++中使用.NET运行时,则会出现谷歌快速搜索。 this crypto library 对于C++,从我的第一次浏览来看,它不是依赖于平台的,因此您可以在不需要调用ADVAPI32.LIB的情况下运行此操作。