Ваш подход только работает в PowerShell Core на Unix-подобных платформах (macOS, Linux), но он не должен использовать его в целях безопасности - он не работает в Windows (ни в Windows PowerShell, ни в PowerShell Core).
Предупреждение безопасности :
[securestring]
на Unix-подобных платформах НЕТ защиты - символы хранятся в незашифрованном виде - шифрование, лежащее в основе [securestring]
только в Windows полагается только на Windows DPAPI .
Если вы сохраните экземпляр [securestring]
в файле через Export-CliXml
на Unix-подобной платформе - например, с помощью Get-Credential | Export-CliXml MyCredentials.xml
- «безопасные» данные (пароль) могут быть легко извлечены любым, кто может прочитать файл . Напротив, в Windows хранится представление с шифрованием DPAPI, которое может быть дешифровано только одним и тем же пользователем на одном компьютере.
Как показывает ваш код, в Unix постоянный экземпляр [securestring]
представляет собой просто "байтовую строку", которая содержит кодовые точки Unicode символов, составляющих содержимое простого текста ; например, [securestring]
, содержащая строку 'test'
, сохраняется как '7400650073007400'
, что можно построить следующим образом:
-join [Text.Encoding]::Unicode.GetBytes('test').ForEach({ $_.Tostring('x2') })
... и преобразован обратно с:
[Text.Encoding]::Unicode.GetString([byte[]] ('7400650073007400' -split '(..)' -ne '' -replace '^', '0x'))
Вкратце: На Unix-подобных платформах (PowerShell Core ) НЕ используйте Get-Credential | Export-CliXml
для сохранения учетных данных - они будут храниться в незашифрованном виде. Чтобы обеспечить какую-либо защиту, вам нужно будет запретить всем остальным доступ на чтение к файлу с помощью прав доступа к файлу .
Для использования только для Windows , если вам нужно избегать Import-CliXml
, вот значительно упрощенное решение , что также должен работать лучше .
Хотя этот код технически также работает на Unix-подобных платформах, он не обеспечивает никакой защиты, как обсуждалось выше.
Обратите внимание, что требуется преобразование командлета DPAPI , зашифрованного в файле CLIXML, в защищенную строку ([securestring]
) с помощью командлета ConvertTo-SecureString
. экземпляр).
# Load the CLIXML file into a [System.Xml.XmlDocument] ([xml]) instance.
($credXml = [xml]::new()).Load($PWD.ProviderPath + '\MyCredentials.xml')
# Take an XPath shortcut that avoids having to deal with namespaces.
# This should be safe, if you know your XML file to have been created with
# Get-Credential | Export-CliXml MyCredentials.xml
$username, $encryptedPassword =
$credXml.SelectNodes('//*[@N="UserName" or @N="Password"]').'#text'
$networkCred = [pscredential]::new(
$username,
(ConvertTo-SecureString $encryptedPassword)
).GetNetworkCredential()
$networkCred.UserName
# $networkCred.Password # CAUTION: This would echo the plain-text password.