我需要在我的脚本中存储SMTP服务器的一些凭据,但我自然不希望密码以明文形式存储。
到目前为止,我一直在加密密码:
"password" | ConvertTo-SecureString -AsPlainText -Force |
ConvertFrom-SecureString
并在像这样的脚本中使用它:
$password = "(the long string generated from above command)"
$username = "Test@testdomain.com"
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username,($password | ConvertTo-SecureString)
但是,在生成$cred
对象时,我收到以下错误:
ConvertTo-SecureString : Key not valid for use in specified state.
答案 0 :(得分:1)
删除ConvertFrom-SecureString
并按照以下方式重新加载:
$Password = "password" | ConvertTo-SecureString -AsPlainText -Force
$username = "Test@testdomain.com"
$cred = New-Object System.Management.Automation.PsCredential($username, $Password)
答案 1 :(得分:0)
在Carbon模块中使用Protect-String的Unprotect-String可能就是您想要的。我一直使用它并且工作得非常好。
Carbon是一个PowerShell模块,用于自动配置运行Windows 7,8,2008和2012的计算机。
答案 2 :(得分:-4)
请仔细阅读以下内容,然后仔细考虑这些要点,然后才能确定这对他的问题没有帮助。
使用PS或.NET机制加密密码是“通过默默无闻的安全”的情况,除非有一个强大的方法来存储密钥。 (通常的“健全方法”是“我所知道的”,“我是什么”(生物识别技术)和“我拥有的东西”。)但默默无闻是OP似乎要求的安全级别(“自然而然我不希望密码以明文形式存储“)。这并没有错。但是,与编译代码时获得某些安全性通过默认情况的情况不同,PS不是这种情况。
但是,安全性取决于“攻击者”被认为是谁。如果您正在处理当前用户生成的密码,则当前用户不是攻击者。但是,您正在处理由其他实体设置的密码,但您需要用户使用它,但看不到它,那么当前用户是潜在的攻击者。 (这种情况的一个示例:将工作站加入域的脚本需要具有正确域权限的用户。您可能希望用户能够作为成像/重新映像其桌面的一部分加入域,但是您不希望他的域用户帐户拥有加入域的权限,因此您的脚本使用了一组您不希望用户知道的不同凭据。我猜OP正在询问用户未分配密码的情况。本回答的其余部分解决了这种情况。
使用PS / .NET方法加密/获取密码是“通过默默无闻的安全性”,因为攻击者只需要在使用密码之前放置一个断点。使用像$ password这样的变量名称,可以很容易地找到设置断点的位置。模糊变量名称(例如调用密码变量$exectionContext
这是PS自动变量的拼写错误)如果1)脚本很短和/或2)很明显什么命令需要密码。
因此,您可以通过设置$password
(或者您称之为var的任何内容)变得棘手来获得可以说是更好的安全性,而不是将密码加密到相当透明且易于反转的方案。它的终极价值。例如,如果密码是“join-thE_domain”,您可以执行以下操作:
...other script code...
$windowTitle="Install/deinstaller joint script"
...other script code...
$paramName = "-th"
...other script code...
$status = "End main"
...other script code...
$subTitle = $windowTitle.substring(20,4)
...other script code...
$count = 32
...other script code...
# Use a regex in the following to make it more obscure
$fixedStatus = $status -replace "n","_" -replace "o",[string][char]$count
...other script code...
# If cmdlet/cmd doesn't support password as a positional parameter then
# write a function that calls cmdlet/cmd and takes password as positional parm
cmdlet-that-needs-password "arg value 1" ("$subTitle$paramName"+$fixedStatus) "arg value 3"
...other script code...
# extra code at the bottom is important to keep someone from
# just scrolling to bottom of script to see password being used
# This extra code could be just dummy code that doesn't really do anything
# Extra code can be placed throughout the script to make it more obscure
...other script code...