Semua keberatan tentang unsecuring SecureString Anda dengan menciptakan System.String dari itu selain , bagaimana hal itu dapat dilakukan?
Bagaimana saya bisa mengubah System.Security.SecureString biasa ke System.String?
Saya yakin banyak dari Anda yang terbiasa dengan SecureString akan menjawab bahwa seseorang tidak boleh mengubah SecureString menjadi string .NET biasa karena menghapus semua perlindungan keamanan. Aku tahu . Tetapi sekarang program saya melakukan semuanya dengan string biasa, dan saya mencoba untuk meningkatkan keamanannya dan meskipun saya akan menggunakan API yang mengembalikan SecureString kepada saya, saya tidak mencoba menggunakannya untuk meningkatkan keamanan saya.
Saya mengetahui Marshal. SecureStringToBSTR, tapi saya tidak tahu bagaimana cara mengambil BSTR itu dan membuat System.String darinya.
Bagi mereka yang mungkin ingin tahu mengapa saya ingin melakukan ini, saya mengambil kata sandi dari pengguna dan mengirimkannya sebagai bentuk html POST untuk mencatat pengguna ke situs web. Jadi ... ini benar-benar harus dilakukan dengan buffer yang dikelola dan tidak terenkripsi. Jika saya bahkan bisa mendapatkan akses ke buffer yang tidak dikelola dan tidak terenkripsi, saya bayangkan saya bisa menulis aliran byte-by-byte pada aliran jaringan dan berharap itu menjaga keamanan kata sandi sepanjang jalan. Saya berharap jawaban untuk setidaknya satu dari skenario ini.
sumber
StopWatch
danSecureStringToString
mengambil 4.6sec untuk dijalankan. Ini lambat bagiku. Adakah yang mendapatkan waktu yang sama atau sesuatu yang lebih cepat?Database.GetConnectionString()
ke dalam kode Anda, untuk mendapatkan secureString saya, yang merupakan bagian jahat yang memakan waktu hampir 5 detik (dan ya saya harus melihat ke dalamnya! :) Kode Anda mengambil 0,00 mili detik di stopwatch saya jadi semuanya bagus. Terima kasih telah mengarahkan saya ke arah yang benar.Jelas Anda tahu bagaimana ini mengalahkan seluruh tujuan SecureString, tapi saya akan menyatakannya kembali.
Jika Anda menginginkan one-liner, coba ini: (.NET 4 dan di atasnya)
Di mana securePassword adalah SecureString.
sumber
[System.Net.NetworkCredential]::new('', $securePassword).Password
''
bukan tipe yang sama[String]::Empty
? JugaNew-Object Net.Credential
tidak berfungsi untuk saya: Tidak dapat menemukan tipe [Net.Kredensial]: verifikasi bahwa rakitan yang berisi tipe ini dimuatDang. tepat setelah memposting ini saya menemukan jawabannya dalam artikel ini . Tetapi jika ada yang tahu bagaimana mengakses buffer yang tidak dikelola, tidak terenkripsi IntPtr yang mengekspos metode ini, satu byte pada suatu waktu sehingga saya tidak harus membuat objek string terkelola darinya untuk menjaga keamanan saya tinggi, silakan tambahkan jawaban. :)
sumber
unsafe
kata kunci danchar*
, cukup panggilbstr.ToPointer()
dan putar.SecureString.Length
.SecureString
tidak mencoba untuk menyembunyikan nilai, itu mencoba untuk mencegah salinan dari nilai yang dibuat menjadi daerah yang tidak dapat ditimpa dengan andal, seperti memori yang dikumpulkan sampah, pagefile, dll. Maksudnya adalah bahwa ketika masaSecureString
hidup berakhir, tentu saja tidak ada salinan rahasia yang tersisa di memori. Itu tidak mencegah Anda membuat dan membocorkan salinan, tetapi itu tidak pernah terjadi.Menurut pendapat saya, metode ekstensi adalah cara paling nyaman untuk menyelesaikan ini.
Saya mengambil jawaban Steve yang luar biasa dari CO dan memasukkannya ke dalam kelas ekstensi sebagai berikut, bersama dengan metode kedua yang saya tambahkan untuk mendukung arah yang lain (string -> string yang aman) juga, sehingga Anda dapat membuat string yang aman dan mengubahnya menjadi string normal setelahnya:
Dengan ini, Anda sekarang dapat dengan mudah mengubah string Anda bolak - balik seperti:
Namun perlu diingat metode decoding hanya digunakan untuk pengujian.
sumber
Saya pikir itu akan menjadi yang terbaik untuk
SecureString
fungsi dependen untuk merangkum logika dependen mereka dalam fungsi anonim untuk kontrol yang lebih baik atas string yang didekripsi dalam memori (setelah disematkan).Implementasi untuk mendekripsi SecureStrings dalam cuplikan ini akan:
finally
blok.Ini jelas membuatnya jauh lebih mudah untuk "membakukan" dan mempertahankan penelepon vs mengandalkan alternatif yang kurang diinginkan:
string DecryptSecureString(...)
fungsi pembantu.Perhatikan di sini, Anda memiliki dua opsi:
static T DecryptSecureString<T>
yang memungkinkan Anda untuk mengakses hasilFunc
delegasi dari pemanggil (seperti yang ditunjukkan dalamDecryptSecureStringWithFunc
metode pengujian).static void DecryptSecureString
hanyalah versi "void" yang mempekerjakanAction
delegasi dalam kasus di mana Anda sebenarnya tidak ingin / perlu mengembalikan apa pun (seperti yang ditunjukkan dalamDecryptSecureStringWithAction
metode pengujian).Contoh penggunaan untuk keduanya dapat ditemukan di
StringsTest
kelas yang disertakan.Strings.cs
StringsTest.cs
Jelas, ini tidak mencegah penyalahgunaan fungsi ini dengan cara berikut, jadi berhati-hatilah untuk tidak melakukan ini:
Selamat coding!
sumber
Marshal.Copy(new byte[insecureString.Length], 0, insecureStringPointer, (int)insecureString.Length);
bukanfixed
bagian?[char]
, tidak[byte]
.String.Empty
, bukan instance yang baru dialokasikan yang dibuat dan dikembalikan olehMarshal.PtrToStringUni()
.Saya membuat metode ekstensi berikut berdasarkan jawaban dari rdev5 . Menyematkan string yang dikelola penting karena mencegah pengumpul sampah untuk berpindah dan meninggalkan salinan yang tidak dapat Anda hapus.
Saya pikir keuntungan dari solusi saya adalah tidak diperlukan kode yang tidak aman.
sumber
System.String
objek akan membuat salinan tanpa penempelan dan unerased. Itu sebabnya ini tidak dibangun ke dalamSecureString
.new char[length]
(atau mengalikanlength
dengansizeof(char)
).action
delegasi tidak membuat salinan dari string sementara, disematkan, kemudian di-zeroed-out, pendekatan ini harus seaman atau tidak aman sepertiSecureString
itu sendiri - untuk menggunakan yang terakhir, representasi teks biasa juga harus dibuat pada beberapa titik, mengingat bahwa string aman bukan konstruksi tingkat OS; keamanan relatif berasal dari mengendalikan masa pakai string itu dan memastikan bahwa itu terhapus setelah digunakan.SecureString
tidak memiliki fungsi anggota dan operator kelebihan beban yang membuat salinan di semua tempat.System.String
tidak.NetworkCredential
konstruktor yang TIDAK menerimaSecureString
.Kode C # ini adalah yang Anda inginkan.
%ProjectPath%/SecureStringsEasy.cs
sumber
Saya berasal dari jawaban ini oleh sclarke81 . Saya suka jawabannya dan saya menggunakan turunan tetapi sclarke81's memiliki bug. Saya tidak punya reputasi jadi saya tidak bisa berkomentar. Masalahnya tampaknya cukup kecil sehingga tidak memerlukan jawaban lain dan saya bisa mengeditnya. Jadi saya lakukan. Itu ditolak. Jadi sekarang kita punya jawaban lain.
sclarke81 Saya harap Anda melihat ini (pada akhirnya):
seharusnya:
Dan jawaban lengkap dengan perbaikan bug:
sumber
Solusi kerja akhir menurut solusi sclarke81 dan perbaikan John Flaherty adalah:
sumber
sumber
BSTR
secara eksplisit, dan itu bukan objek .NET sehingga pengumpul sampah tidak mengurusnya juga. Dibandingkan dengan stackoverflow.com/a/818709/103167 yang diposting 5 tahun sebelumnya dan tidak bocor.Jika Anda menggunakan
StringBuilder
alih - alih astring
, Anda dapat menimpa nilai sebenarnya dalam memori setelah selesai. Dengan begitu kata sandi tidak akan berkeliaran di memori sampai pengumpulan sampah mengambilnya.sumber