DPAPI OF - NCryptProtectSecret returns NTE_ENCRYPTION_FAILURE
DPAPI NG - NCryptProtectSecret returns NTE_ENCRYPTION_FAILURE
我正在尝试使用 DPAPI-NG 加密数据,但在执行 NCryptProtectSecret 时失败,它 returns:
0x80090034 (NTE_ENCRYPTION_FAILURE)
我已经用本地用户 SID 创建了 NCryptCreateProtectionDescriptor:
"SID=S-1-5-21-2942599413-360359348-3087651068-500"
然后我使用这个描述符实例作为 NCryptProtectSecret 的输入,但它不起作用。
如果我使用保护描述符:
"LOCAL=user"
一切似乎都很好,但它不适用于用户或组的 SID。我已经在 Windows Server 2012R2 和 Windows Server 2016 上进行了测试。
有什么想法吗?
这是一个代码示例:
SECURITY_STATUS Status;
PBYTE ProtectedData = NULL;
ULONG ProtectedDataLength = 0;
NCRYPT_DESCRIPTOR_HANDLE DescriptorHandle = NULL;
LPCWSTR ProtectionDescString = L"SID=S-1-5-21-2942599413-360359348-3087651068-500";
Status = NCryptCreateProtectionDescriptor(
ProtectionDescString,
0,
&DescriptorHandle
);
// Status is ERROR_SUCCESS (zero)
LPCWSTR SecretString = L"Some message to protect";
PBYTE Secret = (PBYTE)SecretString;
DWORD SecretLength = (ULONG)( (wcslen(SecretString)+1)*sizeof(WCHAR) );
Status = NCryptProtectSecret(
DescriptorHandle,
0,
PlainText,
PlainTextLength,
NULL, // Use default allocations by LocalAlloc/LocalFree
NULL, // Use default parent windows handle.
&ProtectedData, // out LocalFree
&ProtectedDataLength
);
**// Status == NTE_ENCRYPTION_FAILURE**
将 PlainText 和 PlainTextLength 替换为 Secret 和 SecretLength。
我还没弄清楚问题出在哪里,但在不同的域中一切正常。 Microsoft 还确认我们发送给他们的工作示例是正确的,但他们没有解释问题所在。
我 运行 解决了这个问题,发现原因是我们的域 运行 的功能级别低于 2012。将域升级到 2012 后,问题得到解决。
确定功能级别的一种快速简便的方法是以下 PowerShell cmdlet
[system.directoryservices.activedirectory.Forest]::GetCurrentForest().ForestMode
检查用户 运行 应用程序确实 是 用户
S-1-5-21-2942599413-360359348-3087651068-500
您可以在命令提示符下进行测试:
>whoami /user
USER INFORMATION
----------------
User Name SID
============= ============================================
erbium\zeljko S-1-5-21-2942599413-360359348-3087651068-500
当我尝试使用我实际上没有的组 SID(Domain Users
组)时,我得到了 NTE_ENCRYPTION_FAILURE
。
可能是您的 sid 与 运行 代码不符。
我正在尝试使用 DPAPI-NG 加密数据,但在执行 NCryptProtectSecret 时失败,它 returns:
0x80090034 (NTE_ENCRYPTION_FAILURE)
我已经用本地用户 SID 创建了 NCryptCreateProtectionDescriptor:
"SID=S-1-5-21-2942599413-360359348-3087651068-500"
然后我使用这个描述符实例作为 NCryptProtectSecret 的输入,但它不起作用。
如果我使用保护描述符:
"LOCAL=user"
一切似乎都很好,但它不适用于用户或组的 SID。我已经在 Windows Server 2012R2 和 Windows Server 2016 上进行了测试。
有什么想法吗?
这是一个代码示例:
SECURITY_STATUS Status;
PBYTE ProtectedData = NULL;
ULONG ProtectedDataLength = 0;
NCRYPT_DESCRIPTOR_HANDLE DescriptorHandle = NULL;
LPCWSTR ProtectionDescString = L"SID=S-1-5-21-2942599413-360359348-3087651068-500";
Status = NCryptCreateProtectionDescriptor(
ProtectionDescString,
0,
&DescriptorHandle
);
// Status is ERROR_SUCCESS (zero)
LPCWSTR SecretString = L"Some message to protect";
PBYTE Secret = (PBYTE)SecretString;
DWORD SecretLength = (ULONG)( (wcslen(SecretString)+1)*sizeof(WCHAR) );
Status = NCryptProtectSecret(
DescriptorHandle,
0,
PlainText,
PlainTextLength,
NULL, // Use default allocations by LocalAlloc/LocalFree
NULL, // Use default parent windows handle.
&ProtectedData, // out LocalFree
&ProtectedDataLength
);
**// Status == NTE_ENCRYPTION_FAILURE**
将 PlainText 和 PlainTextLength 替换为 Secret 和 SecretLength。
我还没弄清楚问题出在哪里,但在不同的域中一切正常。 Microsoft 还确认我们发送给他们的工作示例是正确的,但他们没有解释问题所在。
我 运行 解决了这个问题,发现原因是我们的域 运行 的功能级别低于 2012。将域升级到 2012 后,问题得到解决。
确定功能级别的一种快速简便的方法是以下 PowerShell cmdlet
[system.directoryservices.activedirectory.Forest]::GetCurrentForest().ForestMode
检查用户 运行 应用程序确实 是 用户
S-1-5-21-2942599413-360359348-3087651068-500
您可以在命令提示符下进行测试:
>whoami /user
USER INFORMATION
----------------
User Name SID
============= ============================================
erbium\zeljko S-1-5-21-2942599413-360359348-3087651068-500
当我尝试使用我实际上没有的组 SID(Domain Users
组)时,我得到了 NTE_ENCRYPTION_FAILURE
。
可能是您的 sid 与 运行 代码不符。