我开发了一个PowerShell脚本,该脚本处理某些文件并通过SFTP传输它们。为此,每当需要对SFTP服务器进行身份验证时,它都使用SecureString类型从加密的文本文件中读取和解密SFTP用户凭据。这是必需的,因为不允许我将凭据以纯文本格式存储在文件(或脚本本身)中,因为否则将无法通过下一次安全审核。
除脚本外,还有一个单独的配置脚本,必须运行一次以指定sftp用户凭据,对其进行加密并将其保存到文本文件中。这是该配置脚本的(简化)代码:
Write-Output "Please enter the username of the SFTP user."
$username = Read-Host
Write-Output "Please enter the password of the SFTP user"
$password = Read-Host -AsSecureString
$username | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "$scriptroot\Credentials.dat"
$password | ConvertFrom-SecureString | Out-File -Append "$scriptroot\Credentials.dat"
基本上,这两个脚本可以正常工作,并可以实现它们应做的事情。但是,无论出于何种原因,解密都会在某个时候停止工作(有时在几周后,有时在几个月或更长时间之后)。据我所知,如果例如对凭据进行加密的用户的密码发生更改,就会发生这种情况,但事实是,脚本都由专门为运行脚本而创建的同一台计算机用户运行,而没有得到其脚本密码已更改。
我不明白为什么一段时间后这种操作会一遍又一遍地停止,而且我不确定该怎么办。有谁知道弄清楚为什么解密突然停止工作的方法吗?
我还读到Microsoft不再建议对新项目使用SecureString,但是可以替代使用什么呢?我还应该如何安全地将用户凭据存储在文件中,而无需在脚本中或其他位置的其他文件中存储某种纯文本解密密钥呢?
解密只是停止工作真是很奇怪,这听起来很环保。但是,为什么要用这种方式...
Write-Output "Please enter the username of the SFTP user."
$username = Read-Host
Write-Output "Please enter the password of the SFTP user"
$password = Read-Host -AsSecureString
$username | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "$scriptroot\Credentials.dat"
$password | ConvertFrom-SecureString | Out-File -Append "$scriptroot\Credentials.dat"
...与沿着这些路线前进。
$UserCreds = Get-Credential -Message 'Please enter the username of the SFTP credentials'
$UserCreds.GetNetworkCredential().UserName
$UserCreds.GetNetworkCredential().Password
<#
# Results
postanote
password
#>
或者通过这种方式,
Get-Credential -Message 'Please enter the username of the SFTP credentials.' |
Export-Clixml -Path 'D:\temp\SFTPUserCreds.xml'
Get-Content -Path 'D:\temp\SFTPUserCreds.xml'
<#
# Results
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>System.Management.Automation.PSCredential</T>
<T>System.Object</T>
</TN>
<ToString>System.Management.Automation.PSCredential</ToString>
<Props>
<S N="UserName">postanote</S>
<SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb01000000bd0a9dd27ffa41419fb2b289838ebe6400000000020000000000106600000001000020000000ad2e4c96413a3e93e461f600e98f72aa5
e3493bde41ac40491bfd4bedc462152000000000e8000000002000020000000e0016657a9f6e545b55876fa8095143c08046f1361baec0f693a1e823cc6ee0d200000006949857c09b23099dab66fdc3a7e4f7637970dbd3aa13
be11fda7c8de63df70e40000000f9a266cbb34440f64d9a2bdeaaec3a6cda483138e0be29323ca0a523ac475e169793557e74dd208e3d4292aa4fbe5b90fc7023d41c4dd6d01f819366e0587885</SS>
</Props>
</Obj>
</Objs>
#>
不需要解密,只需传递变量名
($UserCreds = Import-Clixml -Path 'D:\Temp\SFTPUserCreds.xml')
<#
# Results
UserName Password
-------- --------
postanote System.Security.SecureString
#>
或者这样
Get-Credential -Message 'Please enter the username of the SFTP credentials.' |
Export-PSCredential -RegistryPath 'HKCU:\software\SFTP' -Name SFTPUserCreds
$UserCred = Import-PSCredential -RegistryPath 'HKCU:\Software\SFTP' -Name SFTPUserCreds
# Or just use Windows Credential Manager
Find-Module -Name '*CredentialManager*' | Format-Table -AutoSize
Version Name Repository Description
------- ---- ---------- -----------
2.0 CredentialManager PSGallery Provides access to credentials in the Windows Credential Manager
...
因此,即使基于您对SecureString的了解,对于大多数人来说,这仍然是一回事,尽管根据我上面显示的内容,我不确定为什么。
无论如何,给上面的一个或多个镜头打一下,看看是否能让您更具一致性。