方法一 使用"凭证管理器"

1.1 创建Windows凭证的普通凭证:

【PowerShell】Powershell脚本中的密码安全_安全


1.2 使用powershell获取凭证信息

PS D:\> Get-StoredCredential -Target 1111
Get-StoredCredential: The term 'Get-StoredCredential' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
PS D:\>

1.3 安装CredentialManager模块:

PS D:\> Install-Module -Name CredentialManager

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the
Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): Y
PS D:\>
PS D:\>

1.4 继续使用powershell获取凭证信息

PS D:\> Get-Command -Module CredentialManager

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-StoredCredential                               2.0        CredentialManager
Cmdlet          Get-StrongPassword                                 2.0        CredentialManager
Cmdlet          New-StoredCredential                               2.0        CredentialManager
Cmdlet          Remove-StoredCredential                            2.0        CredentialManager

PS D:\>
PS D:\>
PS D:\> Get-StoredCredential -Target 1111

UserName                     Password
--------                     --------
root     System.Security.SecureString

PS D:\>

PS D:\> $c = Get-StoredCredential -Target 1111
PS D:\> $c.UserName
root
PS D:\> $c.Password
System.Security.SecureString
PS D:\>

1.5 使用凭证管理器中的凭证:

PS D:\> $c = Get-StoredCredential -Target 1111
PS D:\> $username = $c.UserName
PS D:\> $secure = $c.Password
PS D:\> $cred = New-Object System.Management.Automation.PSCredential($username,$secure)
PS D:\> $DeviceIP = "192.168.11.142"
PS D:\> $port = 22
PS D:\> $session01 = New-SSHSession -ComputerName $DeviceIP -Credential $cred -AcceptKey -Port $port
PS D:\> $result = Invoke-SSHCommand -SessionId $session01.SessionId -Command 'cd /xml && pwd'
PS D:\> $result.Output
/xml
PS D:\>

只能在创建凭证的当前账户下使用;计算机上的其他账户都无法使用。

方法二 执行时输入

这个最简单

$cerd1 = Get-Credential

【PowerShell】Powershell脚本中的密码安全_夏明亮_02

这就只适合图形化界面中手动执行的情况了。

执行的时候输入凭证的用户使用

方法三 使用SecureString

3.1 密码明文写入脚本文件中

PS C:\WINDOWS\system32> $username = "root"
PS C:\WINDOWS\system32> $password = "********"
PS C:\WINDOWS\system32> $DeviceIP = "192.168.11.142"
PS C:\WINDOWS\system32> $port = 22
PS C:\WINDOWS\system32> $secure = $password | ConvertTo-SecureString -AsPlainText -Force
PS C:\WINDOWS\system32> $cred = New-Object System.Management.Automation.PSCredential($username,$secure)
PS C:\WINDOWS\system32> $session01 = New-SSHSession -ComputerName $DeviceIP -Credential $cred -AcceptKey -Port $port
PS C:\WINDOWS\system32> $result = Invoke-SSHCommand -SessionId $session01.SessionId -Command 'cd /xml && pwd'
PS C:\WINDOWS\system32> $result.Output
/xml
PS C:\WINDOWS\system32>

任何有权限访问和执行脚本的用户均可使用,且密码为明文,不安全。

3.2 密码密文写入脚本文件中:

首先,明文密码加密:

PS C:\WINDOWS\system32> $secure = '12345678' | ConvertTo-SecureString -AsPlainText -Force
PS C:\WINDOWS\system32> $secure
System.Security.SecureString
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> $secret = ConvertFrom-SecureString $secure
PS C:\WINDOWS\system32> $secret
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000f5084322e58a964ea05a4cbd6ec38b640000000002000000000010660000000100002000000087ca7777664cd15fa905da31000813ac23d96b44cef9fe98eefe28fc1c086236000000000e800000000200002000000029c626a9a500d2026fcdabedfaa43542f33f98c6e5d0997c12c7f0100a7d0ddf20000000c15fd7937ebab9a2d4066c2b3838f42c94d056604df4191a6e4ba2d9cd55d926400000002fde228d00bdd08ecd93dfb15a3ff8a25836b0036f78f6175a156b8ab23627e2955c9edd34e7af650ee1b2ded2217b01efcd638b8704dac6698f1a60aa90777a
PS C:\WINDOWS\system32>

ConvertFrom-SecureString 命令生成的加密字符串,我们把它保存到文本文件中:

【PowerShell】Powershell脚本中的密码安全_Powershell_03

或者:

ConvertFrom-SecureString $secure | Out-File "c:tempsec.txt"

使用密文密码:

PS C:\WINDOWS\system32> $secure1 = Get-Content 'c:\temp\sec.txt' | ConvertTo-SecureString
PS C:\WINDOWS\system32> $secure1.Length
8
PS C:\WINDOWS\system32> $secure1
System.Security.SecureString
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> $cred = New-Object System.Management.Automation.PSCredential($username,$secure1)
PS C:\WINDOWS\system32> $session01 = New-SSHSession -ComputerName $DeviceIP -Credential $cred -AcceptKey -Port $port
PS C:\WINDOWS\system32> $result = Invoke-SSHCommand -SessionId $session01.SessionId -Command 'cd /xml && pwd'
PS C:\WINDOWS\system32> $result.Output
/xml
PS C:\WINDOWS\system32>

加密密文只能在创建密文的账户下使用,其他用户均无法使用

PS C:\WINDOWS\system32> $secure1 = Get-Content 'c:\temp\sec.txt' | ConvertTo-SecureString
ConvertTo-SecureString : 该项不适于在指定状态下使用。
所在位置 行:1 字符: 44
+ $secure1 = Get-Content 'c:\temp\sec.txt' | ConvertTo-SecureString
+                                            ~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [ConvertTo-SecureString],CryptographicException
    + FullyQualifiedErrorId : ImportSecureString_InvalidArgument_CryptographicError,Microsoft.PowerShell.Commands.Conv
   ertToSecureStringCommand

PS C:\WINDOWS\system32>

方法四 SecureString的安全与移植(自定义加密密钥)

创建自定义的加密key:

key的长度可以是16, 24, 或者32字节。

Function RandomKey {
     $RKey = @()
     For ($i=1; $i -le 24; $i++) {
     [Byte]$RByte = Get-Random -Minimum 0 -Maximum 256
     $RKey += $RByte
     }
     return $RKey
}
$key = RandomKey
Set-Content -Path "C:\temp\sec_key.txt" -Value $key

或者

$key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)
Set-Content -Path "C:\temp\sec_key.txt" -Value $key

使用自定义的key加密SecureString:

$ScureString = ConvertTo-SecureString -String "********" -AsPlainText -Force
$key = Get-Content -Path "C:\temp\sec_key.txt"
$EncryptedPW = ConvertFrom-SecureString -SecureString $ScureString -Key $key
Set-Content -Path "C:\temp\sec_pw.txt" -Value $EncryptedPW

使用自定义key解密SecureString:

$uername = 'root'
$EncryptedPW = Get-Content -Path "C:\temp\sec_pw.txt"
$key = Get-Content -Path "C:\temp\sec_key.txt"
$SecureString = ConvertTo-SecureString -String $EncryptedPW -Key $key
$cred = New-Object System.Management.Automation.PSCredential($username,$SecureString)
$cred.GetNetworkCredential().Password

Example:

#-----user A------
# 1.创建加密密钥
PS C:\WINDOWS\system32> Function RandomKey {
>>      $RKey = @()
>>      For ($i=1; $i -le 24; $i++) {
>>      [Byte]$RByte = Get-Random -Minimum 0 -Maximum 256
>>      $RKey += $RByte
>>      }
>>      return $RKey
>> }
PS C:\WINDOWS\system32> $key = RandomKey
PS C:\WINDOWS\system32> Set-Content -Path "C:\temp\sec_key.txt" -Value $key
PS C:\WINDOWS\system32> $key
109
214
66
202
31
9
224
151
125
51
123
123
250
145
240
188
15
13
137
47
238
25
30
101
PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> Get-Content -Path "C:\temp\sec_key.txt"
109
214
66
202
31
9
224
151
125
51
123
123
250
145
240
188
15
13
137
47
238
25
30
101
PS C:\WINDOWS\system32>

# 2.自定义的key加密SecureString
PS C:\WINDOWS\system32> $ScureString = ConvertTo-SecureString -String "********" -AsPlainText -Force
PS C:\WINDOWS\system32> $ScureString
System.Security.SecureString
PS C:\WINDOWS\system32> $EncryptedPW = ConvertFrom-SecureString -SecureString $ScureString -Key $key
PS C:\WINDOWS\system32> $EncryptedPW
76492d1116743f0423413b16050a5345MgB8AHgAZgBvAHYASgB5AFYAKwBjAFEAVgBhAGIAbgA1ADgAQwBXAFAAUQA0AEEAPQA9AHwAZgBiAGUAMgA5ADYAZgAxADcAOQBlADIAZgAzADIAZABiAGMANAA2ADMANgBkADMANwBkADkAYQBjADAAZgA4ADEANQBmADEAYQA5AGEAZABjADgAYwA4AGQAMABhAGYAMgBmAGUAMwAzADMAYgA5AGIANAA5ADcANAA0ADUAMgA=
PS C:\WINDOWS\system32> Set-Content -Path "C:\temp\sec_pw.txt" -Value $EncryptedPW
PS C:\WINDOWS\system32> Get-Content -Path "C:\temp\sec_pw.txt"
76492d1116743f0423413b16050a5345MgB8AHgAZgBvAHYASgB5AFYAKwBjAFEAVgBhAGIAbgA1ADgAQwBXAFAAUQA0AEEAPQA9AHwAZgBiAGUAMgA5ADYAZgAxADcAOQBlADIAZgAzADIAZABiAGMANAA2ADMANgBkADMANwBkADkAYQBjADAAZgA4ADEANQBmADEAYQA5AGEAZABjADgAYwA4AGQAMABhAGYAMgBmAGUAMwAzADMAYgA5AGIANAA5ADcANAA0ADUAMgA=
PS C:\WINDOWS\system32>


# 3.使用自定义key解密SecureString
PS C:\WINDOWS\system32> $EncryptedPW = Get-Content -Path "C:\temp\sec_pw.txt"
PS C:\WINDOWS\system32> $key = Get-Content -Path "C:\temp\sec_key.txt"
PS C:\WINDOWS\system32> $SecureString = ConvertTo-SecureString -String $EncryptedPW -Key $key

# 4.使用解密后的SecureString
PS C:\WINDOWS\system32> $username = 'root'
PS C:\WINDOWS\system32> $cred = New-Object System.Management.Automation.PSCredential($username,$SecureString)
PS C:\WINDOWS\system32> $DeviceIP = "192.168.11.142"
PS C:\WINDOWS\system32> $port = 22
PS C:\WINDOWS\system32> $session01 = New-SSHSession -ComputerName $DeviceIP -Credential $cred -AcceptKey -Port $port
PS C:\WINDOWS\system32> $result = Invoke-SSHCommand -SessionId $session01.SessionId -Command 'cd /xml && pwd'
PS C:\WINDOWS\system32> $result.Output
/xml
PS C:\WINDOWS\system32>


#-----user B-----
# 5.另一个账户B使用A账户自定义加密的SecureString
PS C:\Users\admin> $EncryptedPW = Get-Content -Path "C:\temp\sec_pw.txt"
PS C:\Users\admin> $key = Get-Content -Path "C:\temp\sec_key.txt"
PS C:\Users\admin> $SecureString = ConvertTo-SecureString -String $EncryptedPW -Key $key
PS C:\Users\admin>
PS C:\Users\admin> $username = 'root'
PS C:\Users\admin> $cred = New-Object System.Management.Automation.PSCredential($username,$SecureString)
PS C:\Users\admin> $DeviceIP = "192.168.11.142"
PS C:\Users\admin> $port = 22
PS C:\Users\admin> $session01 = New-SSHSession -ComputerName $DeviceIP -Credential $cred -AcceptKey -Port $port
PS C:\Users\admin> $result = Invoke-SSHCommand -SessionId $session01.SessionId -Command 'cd /xml && pwd'
PS C:\Users\admin> $result.Output
/xml
PS C:\Users\admin>

【PowerShell】Powershell脚本中的密码安全_安全_04


任何可以访问自定义key文件的用户均可使用;可以在权限上限制对key文件的访问达到限制用户访问的目的。

并且我们也将sec_key.txt和sec_pw.txt复制到其他的计算机中使用。