Ubah string aman menjadi teks biasa


90

Saya bekerja di PowerShell dan saya memiliki kode yang berhasil mengubah kata sandi yang dimasukkan pengguna menjadi teks biasa:

$SecurePassword = Read-Host -AsSecureString  "Enter password" | convertfrom-securestring | out-file C:\Users\tmarsh\Documents\securePassword.txt

Saya telah mencoba beberapa cara untuk mengubahnya kembali, tetapi tidak satupun dari mereka tampaknya berfungsi dengan baik. Baru-baru ini, saya sudah mencoba dengan yang berikut:

$PlainPassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt

#convert the SecureString object to plain text using PtrToString and SecureStringToBSTR
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important step to keep things secure

Ini memberi saya kesalahan juga.

Cannot convert argument "s", with value: "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e43000000000200000000000366000
0c0000000100000008118fdea02bfb57d0dda41f9748a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8
bc271400000038c731cb8c47219399e4265515e9569438d8e8ed", for "SecureStringToBSTR" to type "System.Security.SecureString": "Cannot convert the "01000000
d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f9748a05f10
000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569438d8e8
ed" value of type "System.String" to type "System.Security.SecureString"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:14 char:1
+ $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassw ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Cannot find an overload for "PtrToStringAuto" and the argument count: "1".
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:15 char:1
+ $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Cannot convert argument "s", with value: "", for "ZeroFreeBSTR" to type "System.IntPtr": "Cannot convert null to type "System.IntPtr"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:16 char:1
+ [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important ste ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Password is:  01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f97
48a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569
438d8e8ed

Adakah yang tahu cara yang akan berhasil untuk ini?

Jawaban:


117

Anda sudah dekat, tetapi parameter yang Anda teruskan SecureStringToBSTRharus a SecureString. Anda tampaknya meneruskan hasil ConvertFrom-SecureString, yang merupakan string standar terenkripsi. Jadi panggil ConvertTo-SecureStringini sebelum meneruskan ke SecureStringToBSTR.

$SecurePassword = ConvertTo-SecureString $PlainPassword -AsPlainText -Force
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

4
Saya senang ini berhasil. Berhati-hatilah dengan string Anda, sekarang, ini adalah variabel string tidak aman yang berisi mungkin sesuatu yang penting seperti kata sandi - tidak lagi aman dalam memori proses Anda, dll.
MatthewG

19
Menurut dokumentasi Marshal.SecureStringToBSTR : Karena metode ini mengalokasikan memori tak terkelola yang diperlukan untuk string, selalu kosongkan BSTR setelah selesai dengan memanggil metode ZeroFreeBSTR . Jadi, Anda harus menjalankan berikut pada akhirnya: [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR).
Rosberg Linhares

@RosbergLinhares - Karena kami (mungkin) fokus pada PowerHell, adakah alasan Anda tidak bisa begitu saja $BSTR = $null?
Orangutech

3
@Orangutech Anda tidak dapat hanya menyetel variabel ke $null, karena di sini kita berurusan dengan objek yang tidak dikelola. Anda tidak akan langsung mendapatkan error, tetapi saya rasa Anda mungkin akan mengalami masalah seiring berjalannya waktu.
Rosberg Linhares

1
Selain kebocoran memori yang diakibatkan oleh panggilan yang hilang ZeroFreeBSTR(), seperti yang dinyatakan, penggunaan dari PtrToStringAuto()selalu cacat secara konseptual, dan - sekarang PowerShell adalah lintas platform - gagal pada platform mirip Unix. Seharusnya selalu PtrToStringBSTR() - lihat jawaban ini .
mklement0

83

Anda juga dapat menggunakan PSCredential.GetNetworkCredential ():

$SecurePassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt | ConvertTo-SecureString
$UnsecurePassword = (New-Object PSCredential "user",$SecurePassword).GetNetworkCredential().Password

Saya telah menguji kedua metode tersebut dan keduanya masih benar.
Maximilian Burszley

10
Memberikan suara positif untuk solusi ini karena lebih Powershelly.
Jim

1
Gunakan System.Management.Automation.PSCredentialdi versi PS yang lebih lama ketika nama tipe pendek tidak dikenali.
marsze

1
Lebih pendek:[PSCredential]::new(0, $SecurePassword).GetNetworkCredential().Password
majkinetor

Shorter:[System.Net.NetworkCredential]::new("", $SecurePassword).Password
K. Frank

37

Cara termudah untuk mengubahnya kembali di PowerShell

[System.Net.NetworkCredential]::new("", $SecurePassword).Password

1
Memang tidak perlu melalui PSCredential.
Nicolas Melay

Saya suka pendekatan ini. FYI untuk pecandu kompatibilitas, pengambilan overload konstruktor SecureStringini diperkenalkan di .Net Framework 4.0. Pada PowerShell v2 saya mencoba (New-Object -TypeName System.Net.NetworkCredential -ArgumentList "u",$SecureString).Passwordtetapi sayangnya SecureStringsecara diam-diam diubah menjadi String. Panggilan tampaknya berhasil, tetapi Passwordproperti kemudian menjadi nilai literal "System.Security.SecureString". Hati-hati.
John Rees

19

Di PS 7, Anda dapat menggunakan ConvertFrom-SecureStringdan -AsPlainText:

 $UnsecurePassword = ConvertFrom-SecureString -SecureString $SecurePassword -AsPlainText

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/ConvertFrom-SecureString?view=powershell-7#parameters

ConvertFrom-SecureString
           [-SecureString] <SecureString>
           [-AsPlainText]
           [<CommonParameters>]

3
Ini membuatku gila. Saya mencoba menggunakan sintaks ini di v5 tetapi tidak berhasil.
Tony
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.