【问题标题】:How can I decrypt a string using CryptUnprotectData如何使用 CryptUnprotectData 解密字符串
【发布时间】:2023-01-31 17:54:36
【问题描述】:

我一直在尝试通过 c++ CryptUnprotectData 函数解密一些加密数据(AES 密钥加密 chrome cookie),但我似乎无法让它工作。目前该函数将失败并返回错误代码 13(意思是“参数不正确。”)。到目前为止,这是我的代码:

#include <iostream>
#include <Windows.h>
#include <wincrypt.h>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

std::string GetLastErrorAsString()
{
    DWORD errorMessageID = ::GetLastError();
    if(errorMessageID == 0) {
        return std::string();
    }

    LPSTR messageBuffer = nullptr;

    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    LocalFree(messageBuffer);

    return message;
}

int main()
{



    string data = "(data I want to decode)";
    cout << data;


    DATA_BLOB DataBytes;

    DataBytes.pbData = (BYTE*)data.data();
    DataBytes.cbData = (DWORD)data.size()+1;


    DATA_BLOB output;
    output.pbData = NULL;
    output.cbData = (DWORD)data.size();


    CryptUnprotectData(&DataBytes, NULL, NULL, NULL, NULL, 0, &output);

    cout << GetLastErrorAsString() << endl;
    cout << output.pbData;


    LocalFree(output.pbData);



    return 0;
}

如果有人可以提供任何帮助,将不胜感激。

我尝试了存储参数的数据类型的不同变体,但它仍然返回此错误。

【问题讨论】:

  • 错误 13 == ERROR_INVALID_DATA,根据文档,这意味着完整性检查失败。您确定 chrome 正在使用 CryptProtectData 吗?基本谷歌搜索表明他们正在使用 AES 加密。
  • 抱歉,我可能没有详细说明,我的意思是我正在尝试解密用于解密这些 cookie 的 AES 密钥。

标签: winapi dpapi


【解决方案1】:

我修改了你的代码,如下所示。它只实现简单的解密。 而且数据没有加密,所以CryptUnprotectData()没有返回正确的值。

#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

#pragma comment (lib, "Crypt32.lib")



int main()
{
    // Decrypt data from DATA_BLOB DataOut to DATA_BLOB DataVerify.

//--------------------------------------------------------------------
// Declare and initialize variables.
    string data = ("data I want to decode 
");
    cout << data;

    LPWSTR pDescrOut = NULL;

    DATA_BLOB DataBytes;
    BYTE* pbDataOutput = (BYTE*)data.data();
    DWORD cbDataOutput = strlen((char*)pbDataOutput) + 1;
    DataBytes.pbData = pbDataOutput;
    DataBytes.cbData = cbDataOutput;
    
    //DATA_BLOB DataVerify;
    


    //--------------------------------------------------------------------
    // The buffer DataOut would be created using the CryptProtectData
    // function. If may have been read in from a file.

    //--------------------------------------------------------------------
    //   Begin unprotect phase.
    BOOL res = CryptUnprotectData(
        &DataBytes,
        &pDescrOut,
        NULL,                 // Optional entropy
        NULL,                 // Reserved
        NULL,                 // Here, the optional 
        // prompt structure is not
        // used.
        0,
        &DataBytes);
    if (res==1)
    {
        printf("The decrypted data is: %s
", DataBytes.pbData);
        printf("The description of the data was: %s
", pDescrOut);

    }
    else
    {
        printf("Decryption error!");
    }
//    LocalFree(DataVerify.pbData);
    LocalFree(pDescrOut);
    //LocalFree(DataBytes.pbData);
}

建议添加额外代码时参考Microsoft's official documentation

【讨论】:

  • 感谢你的回答!目前我无法测试它,但我会尽快尝试。
  • 如果确实解决了您的问题,请标记我的答案..
  • 让您久等了!我知道这不太理想,但我目前没有系统来测试你的答案。我可以在几个小时内测试它。
  • 返回的数据只是未加密的数据,虽然函数res等于0
  • @rando314 是的!如果函数成功,函数返回 TRUE(1)。如果函数失败,则返回 FALSE。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-08
  • 2011-01-26
  • 2012-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多