Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

І зберегти його в файл для подальшого використання. Навіщо це потрібно? Хоча б для того, щоб не вводити пароль кожного разу руками. Я б вважав за краще файл формату CSV. І бажано зашифрувати пароль за допомогою надійного криптографічного алгоритму. Для початку збережемо своє ім'я користувача і пароль у відповідні поля екземпляра об'єкта PSCredential.

Розглянемо кілька способів введення даних:

- в діалогове вікно:

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

$ Name = Read-Host -Prompt 'Ім'я користувача'
$ Pass = Read-Host -Prompt 'Пароль' -AsSecureString

$ Cred = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $ name, $ pass

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

$ Name = 'myname' # ім'я користувача
$ Pass = ConvertTo-SecureString -String 'mypass' -AsPlainText -Force # пароль

$ Cred = New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $ name, $ pass

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Звернемо увагу на висновок в консолі властивостей об'єкта: ім'я користувача - 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

Виконаємо код пару раз.

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Прочитаємо вміст CSV-файлу.

$ CsvPath = "$ env: USERPROFILE / cred.csv"
if (Test-Path $ csvPath) Import-Csv -Path $ csvPath | ForEach-Object
>

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Схоже все в ялинку - пароль зашифрований.

Перетворимо дані, отримані з 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 ()>
>

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Дивно, а метод ToString () є.

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

А тепер увага, стежте за руками.

$ 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>
>

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Висновок - пароль в такому вигляді зберігати небезпечно.

"Що ж робити?", - запитаєте ви мене.

Звернемо увагу на командлет перетворення захищеної рядки [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 ""

Нескладний алгоритм вийшов, тут можна (навіть потрібно) наваять свій власний - наскільки фантазія дозволяє.
Тестуємо функцію.

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Пишемо новий скрипт: перед експортом даних в 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

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>
>

Схоже вдало.
Змінимо наш "пін-код" і виконаємо скрипт ще раз.

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Очевидно: пароль, зашифрований в перший раз (іншим ключем) нам отримати не вдалося.

Повернемо первісне значення "пін-коду" і, щоб остаточно переконатися в тому, що все працює як задумано, виконаємо скрипт втретє.

Як отримати пароль з pscredential, vr-online - безкоштовний електронний журнал для всіх

Результат - перший і третій пароль, на другому - помилка, що і було потрібно.

За сім прощаюсь. Всім мир.

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

Схожі статті