И сохранить его в файл для дальнейшего использования. Зачем это нужно? Хотя бы для того, чтобы не вводить пароль каждый раз руками. Я бы предпочел файл формата 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. На мой взгляд решение практически любой задачи, в том числе взлома криптографического алгоритма - вопрос времени и бюджета.















Комментариев нет:
Отправить комментарий
Комментарий будет опубликован после модерации