PowerShell для использования сборки WinSCP .NET с безопасными учетными данными

Я пытаюсь использовать сборку WinSCP .NET с безопасными учетными данными, когда пароль защищен во внешнем файле.

# Load WinSCP .NET assembly
Add-Type -Path "D:\WinSCPnet.dll"

# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.Protocol = [WinSCP.Protocol]::Sftp

# Env
$sessionOptions.HostName = "blabla.com"
$sessionOptions.UserName = "UUUU"
#$sessionOptions.Password = "PPPP"
$sessionOptions.SshHostKeyFingerprint = "XXXXXXXXX"
$remotePath = "/home/UUUU/"

С жестко запрограммированным паролем это работает. Если я хотел бы использовать securestring для пароля, как мне это сделать?

Я старался:

read-host -assecurestring | convertfrom-securestring | out-file D:\securestring.txt

Чтобы сохранить безопасный пароль в файле. Затем в моем сценарии я получаю его обратно:

$sessionOptions.Password = get-Content D:\securestring.txt | convertto-securestring

$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $sessionOptions.UserName, $sessionOptions.Password}

Но это не работает...

3 ответа

Начиная с WinSCP 5.7, сборка принимает SecureString с использованием SessionOptions.SecurePassword,

Смотрите https://winscp.net/eng/docs/library_sessionoptions

Спасибо за вдохновение это улучшение.

Несмотря на то, что сборка хранит пароль в зашифрованном виде в памяти, она все равно должна в конечном итоге расшифровать его. Ожидаются улучшения для ограничения внутренних копий расшифрованного пароля.

Как отметил @Matt, сборка WinSCP .Net не принимает защищенные строки или объекты учетных данных. Вам нужно передать пароль в виде текстовой строки. Вы можете сохранить защищенную строку в файле, хотя:

Read-Host 'Enter password' -AsSecureString |
  ConvertFrom-SecureString |
  Out-File 'C:\password.txt'

и использовать PSCredential объект для извлечения расшифрованного пароля из защищенной строки после того, как вы прочитали его из файла:

$un   = 'username'
$pw   = Get-Content 'C:\password.txt' | ConvertTo-SecureString
$cred = New-Object Management.Automation.PSCredential $un, $pw

try {
  Add-Type -Path 'WinSCPnet.dll'

  $opt = New-Object WinSCP.SessionOptions
  $opt.Protocol = [WinSCP.Protocol]::Sftp
  $opt.HostName = 'example.org'
  $opt.UserName = $cred.UserName
  $opt.Password = $cred.GetNetworkCredential().Password
  $opt.SshHostKeyFingerprint = 'ssh-rsa 2048 ...'

  $sftp = New-Object WinSCP.Session

  $sftp.Open($opt)
  ...
} catch {
  ...
} finally {
  if ($sftp) { $sftp.Dispose() }
}

Пример кода WinSCP взят из документации.

Однако обратите внимание, что пароль должен быть сохранен тем же пользователем, который запускает сценарий SFTP PowerShell, поскольку ключ шифрования получен из пароля этого пользователя.

Согласно WinSCP свойство пароля поддерживает только строку. Таким образом, попытка передать безопасную строку не будет работать. Если вы действительно хотите сохранить пароль в файле, вы можете попытаться сохранить его как защищенную строку, но в целом это действительно плохая идея, поскольку ее можно защитить так же легко (также не уверен, если это возможно). Я рекомендую следующий вариант.

# Only stored in memory which is safer.
$sessionOptions.Password = read-host

Если ваше сердце настроено на что-то другое, вы можете попробовать это. Просто знайте, по предыдущим причинам я не оправдываю это. Кроме того, я должен посмотреть, работает ли он, потому что, похоже, вы не можете вывести securestring в файл.

read-host | out-file D:\securestring.txt
$sessionOptions.Password = get-Content D:\securestring.txt

Ансгар объясняет, что я не знал, было возможно. Вы можете сохранить защищенную строку в файле и использовать ее в другом месте.

Другие вопросы по тегам