Так или иначе каждый человек, работающий с написанием скриптов рано или поздно сталкивается с тем что нужно использовать пароли в скриптах. Если это безответственный человек, то он просто вбивает пароль в скрипт в открытом виде и забывает про это.
Но есть вторая категория людей, которые уже не хотят хранить пароль в открытом виде, кстати в эту группу также могут и перейти люди с первой группы, особенно если они уже слили пароль однажды.
Export-Clixml
Наш первый вариант — это команда Export-Clixml
, которая просто сохраняет пароль в xml файл. Т.е. суть работы следующая:
- Вы экспортируете пароль в файл под текущим пользователем, под которым будете запускать скрипт
- Удостоверяетесь что доступ к этому файлу есть только у этого пользователя
- Уже используя команду
Import-CliXml
импортируете пароль в свой скрипт - Рекомендация от меня если возможно запретить этому пользователю вход в систему и сделать файл скрытым
Скажу сразу что этот вариант мне не нравится. Да вы получите доступ к файлу с паролем только под этим пользователем. Но не забываем несколько вещей:
- Малейший шанс того что кто-то зайдёт под этим пользователем в систему всё же существует
- Администратор системы может получить доступ к любым файлам, если знает, как
#ask for password
$pwd = Get-Credential myuser
#store password in file
$pwd | Export-CLiXml password.clixml
# Make files hidden
(get-item password.clixml).Attributes += 'Hidden'
#get password from file
$password= Import-CliXml password.clixml
ConvertTo-SecureString
Вариант второй уже нравится мне больше. Тут мы используем команду ConvertTo-SecureString
которая преобразует обычную строку в безопасную. Также для большей безопасности то, что мы получили от команды ConvertTo-SecureString
будем дополнительно шифровать, с использованием файл ключа. Суть работы следующая:
- Мы создаём файл ключ, который дальше будет использоваться для создания зашифрованной строки
- Создаём текстовый файл, в котором сохраняем пароль в чистом виде (потом удаляем)
- Преобразовываем обычную строку в безопасную (
ConvertTo-SecureString
) - Преобразовываем безопасную строку в зашифрованную используя ключ (
ConvertFrom-SecureString
) - Сохраняем полученное в файл
- Используем в скриптах расшифровывая с использованием файл ключа
Тут уже как минимум наш пароль в файле становится зашифрованным, а не лежит в открытом виде. Также без ключа не получится расшифровать пароль.
#path for key file
$keyFile = "keyfile.key"
#path for file which contain password (must be deleted after first run)
$insecurePassFile = "insecurePass.txt"
##path for file which will be contain encrypted password
$securePassFile = "securePass.txt"
#Create key file
$key = New-Object Byte[] 32
$key | Out-File $keyFile
(get-item $keyFile).Attributes += 'Hidden'
#Convert password to secure string and then to encrypted string
$key = Get-Content $keyFile
$password = Get-Content $insecurePassFile | Select-Object -First 1 | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString -key $key
$password | Out-File $securePassFile
(get-item $securePassFile).Attributes += 'Hidden'
Команды выше можно запустить всего один раз, и после выполнения обязательно удалить файл с открытым паролем. Только не обновите файл с зашифрованным паролем.
После можно уже использовать эту схему у себя в скрипте:
#Get password in secure string
$SecurePassword = Get-Content $securePassFile | ConvertTo-SecureString -Key $key
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecurePassword
#Get password
$pwd = [System.Net.NetworkCredential]::new("", ( Get-Content $securePassFile | ConvertTo-SecureString -Key $key ) ).Password
$pwd
$pwd2 = $Credentials.GetNetworkCredential().Password
$pwd2
ConvertTo-SecureString
Вариант выше конечно же хорош, но мне этого еще недостаточно. Ну что тебе не нравится тут? - спросите вы. А не нравится мне то, что тут присутствует файл ключ, который всё также может стырить какой-нибудь жулик (жулик не воруй).
И что можно сделать? Да по сути ничего не надо особо менять, выполняем всё тоже самое только без ключа (ConvertFrom-SecureString
). Магия тут вся заключается в Windows Data Protection API, благодаря которой вместо ключа будет не файл, а ваша учетная запись WIndows. Да, да вот такая замечательная новость, т.е. для того чтобы добраться до пароля жулику нужно будет залогинится под вашей учетной записью и именно на этом же хосте.
#path for file which contain password (must be deleted after first run)
$insecurePassFile = "insecurePass.txt"
##path for file which will be contain encrypted password
$securePassFile = "securePass.txt"
#Convert password to secure string and then to encrypted string
$password = Get-Content $insecurePassFile | Select-Object -First 1 | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString
$password | Out-File $securePassFile
(get-item $securePassFile).Attributes += 'Hidden'
После чего попробуйте выполнить команды ниже от разных пользователей Windows.
#Get password in secure string
$SecurePassword = Get-Content $securePassFile | ConvertTo-SecureString
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $SecurePassword
#Get password
$pwd = [System.Net.NetworkCredential]::new("", ( Get-Content $securePassFile | ConvertTo-SecureString ) ).Password
$pwd
$pwd2 = $Credentials.GetNetworkCredential().Password
$pwd2
Заключение
Для меня самым идеальным вариантом является третий по счёту. Возможность того, что кто-то сворует ваш пароль, а потом ещё и залогинится на том же хосте и найдёт файл с зашифрованным паролем невысокий.
Комментарии