c++ - 将 Powershell SecureString 传递给 C++ 程序?

标签 c++ powershell encryption securestring dpapi

我有一个 native 程序,它接受在命令行中传递的密码。该密码显示在服务器日志中,因此我想在进入命令行之前通过加密来混淆它。然后我会在程序中解密它并像以前一样使用它。我的想法是,我使用 powershell 创建一个带密码的 SecureString,然后使用 ConvertFrom-SecureString 使其成为可打印的文本字符串。然后将该字符串通过命令行传递给 native c++ 程序。从那里,我将其解码回二进制加密形式,然后将其解密回原始纯文本密码。简单吧?

从很少的文档中,我认为 ConvertFrom-SecureString 执行 Base64 编码以使二进制 SecureString 成为可打印文本。谁能证实这一点? 我使用 ATL::Base64Decode() 恢复二进制字节。这似乎在比较原始和解码的前 20 个字节时起作用。

之后,我尝试解密 SecureString 字节。同样,一些文档似乎暗示 SecureString 加密是使用机器 key (或用户 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;
}

最佳答案

据我所知,查看 dotPeek 中的二进制文件,ConvertFrom-String 正在使用 SecureStringToCoTaskMemUnicode 将安全字符串有效负载转换为字节数组。该字节数组以十六进制形式返回,例如byte.ToString("x2).

这假设您正在使用 DPAPI,而不是在 ConvertFrom-SecureString 上使用 Key 或 SecureKey 参数。

所以在你的 C++ 程序中不要使用 Base64Decode,只需将每两个字符解析为一个十六进制字节即可。然后对生成的字节数组(填充到 DATA_BLOB 中)调用 CryptUnprotectData。

关于c++ - 将 Powershell SecureString 传递给 C++ 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32574728/

相关文章:

c++ - OpenGL 减慢 5k 点

powershell - 其中对象 : Cannot bind parameter 'FilterScript'

c# - WinRT 中的 Rijndael 解密

java - 加密类在 java 中工作但在 android 中不工作,为什么?我还可以做些什么?

java - 无效 key 异常 java.security.InvalidKeyException : No installed provider supports this key: (null)

c++ - 编辑 rc 文件,然后在 VC 对话框向导中打开它时,由于 TBS_NOTIFYBEFOREMOVE,出现错误 RC2104

c++ - 如何创建 std::tuple 的别名?

c++ - 像 'T' 这样的模板参数是否总是被解释为每个值?

powershell - 监听多个组播端口

performance - VBS vs PowerShell : Which is lighter?