И сохранить его в файл для дальнейшего использования. Зачем это нужно? Хотя бы для того, чтобы не вводить пароль каждый раз руками. Я бы предпочел файл формата CSV. И желательно зашифровать пароль с помощью надежного криптографического алгоритма. Для начала сохраним имя пользователя и пароль в соответствующие поля экземпляра объекта PSCredential.
Рассмотрим несколько способов ввода данных:
- в диалоговое окно:
- в консоль:
- сразу в код:
Обратим внимание на вывод в консоли свойств объекта: имя пользователя - myname, пароль - System.Security.SecureString.
Похоже наш пароль надежно защищен.
Отправим данные в CSV-файл на хранение.
Выполним код пару раз.
Прочитаем содержимое CSV-файла.
Похоже все в елочку - пароль зашифрован.
Преобразуем данные, полученные из CSV-файла, в экземпляры объекта PSCredential, для чего создадим объекты с помощью конструктора, и попробуем преобразовать свойство Password каждого объекта в строку.
Странно, а метод ToString() есть...
А теперь внимание, следите за руками...
... пароль получен.
Вывод - пароль в таком виде хранить небезопасно.
"Что же делать?", - спросите вы меня :).
Обратим внимание на командлет преобразования защищенной строки [System.Security.SecureString] в шифрованную строку [System.String] - ConvertFrom-SecureString.
Именно его мы использовали в процессе подготовки пароля к экспорту в CSV-файл.
Командлет предлагает нам пару параметров для шифрования: Key и SecureKey.
Предлагаю использовать в качестве ключа массив байт, состоящий из 16, 24 или 32 (по умолчанию) элементов - 128, 192 или 256-битный ключ соответственно.
Запоминать все элементы массива - хлопотно.
Упростим: напишем функцию, которая будет получать 4 цифры (как пин-код - худо-бедно запомнить можно) и возвращать массив байт заданной длины.
Несложный алгоритм получился, здесь можно (даже нужно) наваять свой собственный - насколько фантазия позволяет.
Тестируем функцию.
Пишем новый скрипт: перед экспортом данных в CSV-файл шифруем пароль алгоритмом AES, после чего спустя пару секунд пытаемся его прочитать.
Выполняем скрипт.
Похоже удачно.
Изменим наш "пин-код" и выполним скрипт еще раз.
Очевидно: пароль, зашифрованный в первый раз (другим ключом) нам получить не удалось.
Вернем первоначальное значение "пин-кода" и, чтобы окончательно убедиться в том, что все работает как задумано, выполним скрипт в третий раз.
Результат - первый и третий пароль, на втором - ошибка, что и требовалось.
За сим прощаюсь. Всем мир.
p.s. На мой взгляд решение практически любой задачи, в том числе взлома криптографического алгоритма - вопрос времени и бюджета.
Рассмотрим несколько способов ввода данных:
- в диалоговое окно:
$cred = Get-Credential $cred.UserName $cred.Password
- в консоль:
$name = Read-Host -Prompt 'Имя пользователя' $pass = Read-Host -Prompt 'Пароль' -AsSecureString $cred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $name, $pass $cred.UserName $cred.Password
- сразу в код:
$name = 'myname' # имя пользователя $pass = ConvertTo-SecureString -String 'mypass' -AsPlainText -Force # пароль $cred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $name, $pass $cred.UserName $cred.Password
Обратим внимание на вывод в консоли свойств объекта: имя пользователя - myname, пароль - System.Security.SecureString.
Похоже наш пароль надежно защищен.
Отправим данные в CSV-файл на хранение.
$name = 'myname' # имя пользователя $pass = ConvertTo-SecureString -String 'mypass' -AsPlainText -Force # пароль $cred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $name, $pass New-Object -TypeName PSObject -Property @{ ` 'UserName'=$cred.UserName; ` 'Password'= (ConvertFrom-SecureString $cred.Password)` } | Export-Csv -Path "$env:USERPROFILE/cred.csv" -Encoding UTF8 -NoTypeInformation -Append
Выполним код пару раз.
Прочитаем содержимое CSV-файла.
$csvPath = "$env:USERPROFILE/cred.csv" if (Test-Path $csvPath) { Import-Csv -Path $csvPath | ForEach-Object {$_} }
Похоже все в елочку - пароль зашифрован.
Преобразуем данные, полученные из CSV-файла, в экземпляры объекта PSCredential, для чего создадим объекты с помощью конструктора, и попробуем преобразовать свойство Password каждого объекта в строку.
$csvPath = "$env:USERPROFILE/cred.csv" if (Test-Path $csvPath) { Import-Csv -Path $csvPath | ForEach-Object {( ` New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $_.UserName, (ConvertTo-SecureString $_.Password) ` ).Password.ToString()} }
Странно, а метод ToString() есть...
А теперь внимание, следите за руками...
$csvPath = "$env:USERPROFILE/cred.csv" if (Test-Path $csvPath) { Import-Csv -Path $csvPath | ForEach-Object {( ` New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $_.UserName, (ConvertTo-SecureString $_.Password) ` ).GetNetworkCredential().Password} }
... пароль получен.
Вывод - пароль в таком виде хранить небезопасно.
"Что же делать?", - спросите вы меня :).
Обратим внимание на командлет преобразования защищенной строки [System.Security.SecureString] в шифрованную строку [System.String] - ConvertFrom-SecureString.
Именно его мы использовали в процессе подготовки пароля к экспорту в CSV-файл.
'Password'= (ConvertFrom-SecureString $cred.Password)
Командлет предлагает нам пару параметров для шифрования: Key и SecureKey.
Предлагаю использовать в качестве ключа массив байт, состоящий из 16, 24 или 32 (по умолчанию) элементов - 128, 192 или 256-битный ключ соответственно.
Запоминать все элементы массива - хлопотно.
Упростим: напишем функцию, которая будет получать 4 цифры (как пин-код - худо-бедно запомнить можно) и возвращать массив байт заданной длины.
function Get-Key { [CmdletBinding()] param( [Parameter(Mandatory=$True, Position=0, HelpMessage="Четыре символа пин-кода")] [byte[]] $pin, [Parameter(Position=1, HelpMessage="Длина ключа - 16, 24 или 32 байт")] [int] $len = 32 ) Write-Verbose $pin.Length if ($pin.Length -ne 4) { Write-Error "Количество символов пин-кода должно быть равно 4" } if (($len -ne 16) -and ($len -ne 24) -and ($len -ne 32)) { Write-Error "Длина ключа должна быть 16, 24 или 32 байт" } $len = $len/4 [byte[]]$key = @() for ($i = 0; $i -lt $len; $i++) { for ($j = 0; $j -lt $pin.Length; $j++) { $key += $pin[$j] } } Write-Output $key } (Get-Key 1,2,3,8 -Verbose) -join ""
Несложный алгоритм получился, здесь можно (даже нужно) наваять свой собственный - насколько фантазия позволяет.
Тестируем функцию.
Пишем новый скрипт: перед экспортом данных в CSV-файл шифруем пароль алгоритмом AES, после чего спустя пару секунд пытаемся его прочитать.
function Get-Key { [CmdletBinding()] param( [Parameter(Mandatory=$True, Position=0, HelpMessage="Четыре символа пин-кода")] [byte[]] $pin, [Parameter(Position=1, HelpMessage="Длина ключа - 16, 24 или 32 байт")] [int] $len = 32 ) if ($pin.Length -ne 4) { Write-Error "Количество символов пин-кода должно быть равно 4" } if (($len -ne 16) -and ($len -ne 24) -and ($len -ne 32)) { Write-Error "Длина ключа должна быть 16, 24 или 32 байт" } $len = $len/4 [byte[]]$key = @() for ($i = 0; $i -lt $len; $i++) { for ($j = 0; $j -lt $pin.Length; $j++) { $key += $pin[$j] } } Write-Output $key } $key = Get-Key 1,2,3,8 $name = 'myname' # имя пользователя $pass = ConvertTo-SecureString -String 'mypass' -AsPlainText -Force # пароль $cred = New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $name, $pass $csvPath = "$env:USERPROFILE/cred2.csv" New-Object -TypeName PSObject -Property @{ ` 'UserName'=$cred.UserName; ` 'Password'= (ConvertFrom-SecureString -SecureString $cred.Password -Key $key)` } | Export-Csv -Path "$csvPath" -Encoding UTF8 -NoTypeInformation -Append Start-Sleep -Seconds 2 if (Test-Path $csvPath) { Import-Csv -Path $csvPath | ForEach-Object {( ` New-Object -TypeName System.Management.Automation.PSCredential ` -ArgumentList $_.UserName, (ConvertTo-SecureString $_.Password -Key $key) ` ).GetNetworkCredential().Password} }
Выполняем скрипт.
Похоже удачно.
Изменим наш "пин-код" и выполним скрипт еще раз.
Очевидно: пароль, зашифрованный в первый раз (другим ключом) нам получить не удалось.
Вернем первоначальное значение "пин-кода" и, чтобы окончательно убедиться в том, что все работает как задумано, выполним скрипт в третий раз.
Результат - первый и третий пароль, на втором - ошибка, что и требовалось.
За сим прощаюсь. Всем мир.
p.s. На мой взгляд решение практически любой задачи, в том числе взлома криптографического алгоритма - вопрос времени и бюджета.
Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации