如何将Powershell的SecureString传递给C++程序?

3
我有一个本地程序,需要通过命令行传递密码。该密码会显示在服务器日志中,因此我希望在放入命令行之前对其进行加密以混淆密码。然后在程序中解密并像以前一样使用它。 我使用powershell创建SecureString密码,然后使用ConvertFrom-SecureString将其转换为可打印的文本字符串。然后将该字符串传递到本地C ++程序的命令行。从那里,我将其解码回到二进制加密形式,然后再将其解密回原始明文密码。简单吧?
根据简单的文档,我认为ConvertFrom-SecureString会进行Base64编码,以使二进制SecureString变为可打印的文本。可以有人证实吗?我使用ATL :: Base64Decode()恢复二进制字节。与原始和解码后的前20个字节进行比较,这似乎有效。
之后,我试图解密SecureString字节。同样,某些文档似乎暗示SecureString加密是使用Machine Key(或User Session Key)完成的。基于此,我正在尝试使用DPAPI CryptUnprotectData方法进行解密。然而,我收到“(0x8007000d)数据无效”的解密失败。听起来这会奏效吗?如果是这样,请问我偏离了哪里的正确方向?
这是解密方法...
// Decrypts an encoded and encrypted string with DPAPI and Machine Key, returns the decrypted string 
static HRESULT Decrypt(CStringW wsEncryptedBase64, OUT CStringW& wsPlainText)
{
    HRESULT hr = S_OK;
    DATA_BLOB dbIn = { 0 };
    DATA_BLOB dbOut = { 0 };

    const wchar_t *pos = wsEncryptedBase64.GetBuffer(wsEncryptedBase64.GetLength());

    dbIn.cbData = wsEncryptedBase64.GetLength() / 2;
    dbIn.pbData = (byte*)malloc(dbIn.cbData * sizeof(byte));
    int num = 0;
    for (size_t i = 0; i < dbIn.cbData; i += 1)
    {
        swscanf_s(pos, L"%2hhx", &num);
        dbIn.pbData[i] = num;
        pos += sizeof(wchar_t);
    }

    if (::CryptUnprotectData(&dbIn, NULL, NULL, NULL, NULL,
        CRYPTPROTECT_UI_FORBIDDEN, &dbOut))
    {
        wsPlainText = CStringW(reinterpret_cast< wchar_t const* >(dbOut.pbData), dbOut.cbData / 2);
    }
    else
    {
        hr = HRESULT_FROM_WIN32(::GetLastError());
        if (hr == S_OK)
        {
            hr = SEC_E_DECRYPT_FAILURE;
        }
    }

    return hr;
}

您可能也想分享PowerShell加密代码。 - Maarten Bodewes
1个回答

1

根据我在dotPeek中观察到的二进制代码,ConvertFrom-String使用SecureStringToCoTaskMemUnicode将安全字符串有效载荷转换为字节数组。该字节数组以十六进制形式返回,例如 byte.ToString("x2)

这假定您正在使用DPAPI,并且没有在ConvertFrom-SecureString上使用Key或SecureKey参数。

因此,在您的C++程序中,请勿使用Base64Decode,只需将每两个字符解析为十六进制字节。然后将其放入DATA_BLOB中的字节数组中调用CryptUnprotectData。


完美的答案!一旦我转移到对输入字符串进行简单解码,它就完美地工作了。 这是解决方案(仍需要一些清理和错误处理... - RyanL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接