ProtectedData.Unprotect方法无法解密

时间:2011-06-02 19:42:44

标签: .net powershell cruisecontrol.net dpapi

我们有一个构建过程需要解密密码,然后用它来连接数据库。我们使用数据保护API(DPAPI)使用PowerShell加密构建服务器上的计算机范围内的密码(我使用自己的域帐户登录):

[Security.Cryptography.ProtectedData]::Protect( $passwordBytes, $null, [Security.Cryptography.DataProtectionScope]::LocalMachine );

解密也在PowerShell脚本中完成,该脚本由CruiseControl.NET执行,作为构建用户运行:

 [Security.Cryptography.ProtectedData]::Unprotect( $encryptedbytes, $null, [Security.Cryptography.DataProtectionScope]::LocalMachine );

然而,对Unprotect的调用失败,并显示以下消息:“密钥无法在指定状态下使用。”。 According to the docs,使用模拟可能会发生此错误,模拟代码应加载用户的个人资料。

出于安全考虑,构建用户被拒绝通过终端服务登录权限。为了测试这个问题,我以自己的身份登录到构建服务器,然后使用runas以构建用户的身份打开PowerShell提示符:

runas /profile /user:DOMAIN\BUILDUSER powershell.exe

然后我运行PowerShell脚本来取消保护/解密密码,并得到同样的错误。

我使用Process Monitor来监视任何失败或访问被拒绝的事件,并且没有任何事件。

当我使用自己的域帐户登录时,我可以解密密码。

发生了什么事?我的构建用户的个人资料是否未加载?是否有某些安全设置我不知道要启用它?为什么我不能解密密码?

2 个答案:

答案 0 :(得分:2)

开发人员错误。事实证明我在CurrentUser范围加密,而不是LocalMachine范围。我更新了我的脚本,现在一切正常。

答案 1 :(得分:1)

您是否注意在文件中对加密的ByteArray进行编码的方式。在我的下面提取我在我的一个服务器上为连接字符串做的方式(我在这里用输入的字符串替换)

转换为Base64将其放入配置文件

Clear-Host

Add-Type -assembly System.Security

$passwordASCII = Read-Host -Prompt "Enter Password"

$bakCryptedPWD_ByteArray = [System.Security.Cryptography.ProtectedData]::Protect( $passwordASCII.tochararray(), $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine )

Set-Content -LiteralPath c:\Temp\pass.txt -Value ([Convert]::ToBase64String($bakCryptedPWD_ByteArray))

返回字符串以ANSI字符为例(密码中可能包含特殊字符)

Clear-Host

Add-Type -assembly System.Security

$resCryptedPWD_ByteArray = [Convert]::FromBase64String((Get-Content -LiteralPath c:\Temp\pass.txt))

$clearPWD_ByteArray = [System.Security.Cryptography.ProtectedData]::Unprotect( $resCryptedPWD_ByteArray, $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine )

$enc = [system.text.encoding]::Default

$enc.GetString($clearPWD_ByteArray)