Все оговорки о unsecuring вашего SecureString пути создания System.String из него в стороне , как это может быть сделано?
Как я могу преобразовать обычный System.Security.SecureString в System.String?
Я уверен, что многие из вас, кто знаком с SecureString, ответят, что никогда не следует преобразовывать SecureString в обычную строку .NET, поскольку она удаляет все средства защиты. Я знаю . Но сейчас моя программа все равно делает все с обычными строками, и я пытаюсь повысить ее безопасность, и хотя я собираюсь использовать API, который возвращает мне SecureString, я не пытаюсь использовать это для повышения своей безопасности.
Я знаю о Marshal.SecureStringToBSTR, но я не знаю, как взять этот BSTR и сделать из него System.String.
Для тех, кто может потребовать, чтобы узнать, почему я хотел бы это сделать, я беру пароль от пользователя и отправляю его в виде HTML-формы POST для входа пользователя на веб-сайт. Итак ... это действительно нужно делать с помощью управляемых незашифрованных буферов. Если бы я мог даже получить доступ к неуправляемому, незашифрованному буферу, я представлял бы, что я мог бы делать побитовую запись потока в сетевом потоке и надеяться, что это обеспечивает безопасность пароля на всем пути. Я надеюсь на ответ хотя бы на один из этих сценариев.
источник
StopWatch
иSecureStringToString
взял 4,6 секунды для запуска. Это медленно для меня. Кто-нибудь получает такое же время или что-то быстрее?Database.GetConnectionString()
в ваш код, чтобы получить свою secureString, которая была злой частью, которая занимала почти 5 секунд (и да, я должен посмотреть на это! :) Ваш код занял 0,00 мили секунды в моем секундомере, так что это все хорошо. Спасибо, что указал мне правильное направление.Очевидно, вы знаете, как это разрушает всю цель SecureString, но я все равно переформулирую.
Если вы хотите использовать одну строку, попробуйте это: (только для .NET 4 и выше)
Где securePassword является SecureString.
источник
[System.Net.NetworkCredential]::new('', $securePassword).Password
''
не тот же тип, что и[String]::Empty
? ТакжеNew-Object Net.Credential
не работает для меня: не удается найти тип [Net.Credential]: убедитесь, что сборка, содержащая этот тип загруженDang. сразу после публикации я нашел ответ глубоко в этой статье . Но если кто-то знает, как получить доступ к неуправляемому, незашифрованному буферу IntPtr, предоставляемому этим методом, по одному байту за раз, чтобы мне не приходилось создавать из него управляемый строковый объект для поддержания высокого уровня безопасности, добавьте ответ. :)
источник
unsafe
ключевое слово и achar*
, просто позвонитеbstr.ToPointer()
и приведите.SecureString.Length
.SecureString
не пытается скрыть значение, он пытается предотвратить копирование значения в регионы, которые невозможно перезаписать, например, память для сбора мусора, файл подкачки и т. Д. Смысл в том, что по окончании времениSecureString
жизни абсолютно копия секрета не остается в памяти. Это не мешает вам делать и передавать копию, но никогда не делает.На мой взгляд, методы расширения являются наиболее удобным способом решения этой проблемы.
Я взял превосходный ответ Стива в CO и поместил его в класс расширения следующим образом, вместе со вторым методом, который я добавил для поддержки другого направления (строка -> безопасная строка), чтобы вы могли создать безопасную строку и преобразовать ее в нормальная строка впоследствии:
Теперь вы можете просто конвертировать ваши строки назад и вперед так:
Но имейте в виду, что метод декодирования должен использоваться только для тестирования.
источник
Я думаю, что для
SecureString
зависимых функций было бы лучше инкапсулировать свою зависимую логику в анонимную функцию для лучшего контроля за расшифрованной строкой в памяти (когда-то закрепленной).Реализация для расшифровки SecureStrings в этом фрагменте будет:
finally
блоке.Это, очевидно, значительно упрощает «стандартизацию» и поддержку вызывающих абонентов по сравнению с использованием менее желательных альтернатив:
string DecryptSecureString(...)
вспомогательной функции.Обратите внимание, у вас есть два варианта:
static T DecryptSecureString<T>
который позволяет получить доступ к результатуFunc
делегата от вызывающей стороны (как показано вDecryptSecureStringWithFunc
методе test).static void DecryptSecureString
это просто «пустая» версия, которая используетAction
делегата в тех случаях, когда вы на самом деле не хотите / не должны ничего возвращать (как продемонстрировано вDecryptSecureStringWithAction
методе test).Пример использования для обоих можно найти в
StringsTest
включенном классе.Strings.cs
StringsTest.cs
Очевидно, что это не предотвращает злоупотребление этой функцией следующим образом, поэтому будьте осторожны, чтобы этого не делать:
Удачного кодирования!
источник
Marshal.Copy(new byte[insecureString.Length], 0, insecureStringPointer, (int)insecureString.Length);
вместоfixed
раздела?[char]
, а не[byte]
.String.Empty
, не недавно выделенный экземпляр, созданный и возвращенныйMarshal.PtrToStringUni()
.Я создал следующие методы расширения на основе ответа от rdev5 . Прикрепление управляемой строки важно, поскольку она не позволяет сборщику мусора перемещать ее и оставлять копии, которые вы не можете стереть.
Я думаю, что преимущество моего решения состоит в том, что небезопасный код не нужен.
источник
System.String
объектом будет создавать не закрепленные и неуничтоженные копии. Вот почему это не встроеноSecureString
.new char[length]
(или умножитьlength
наsizeof(char)
).action
делегат не создает копии временной, закрепленной, а затем обнуляемой строки, этот подход должен быть таким же безопасным, как иSecureString
сам по себе, - чтобы использовать последнюю, текстовое представление также должно быть созданным в какой-то момент, учитывая, что защищенные строки не являются конструкциями уровня ОС; Относительная безопасность достигается за счет контроля времени жизни этой строки и обеспечения ее удаления после использования.SecureString
не имеет функций-членов и перегруженных операторов, которые делают копии повсюду.System.String
делает.NetworkCredential
конструктору, который принимает aSecureString
.Этот код C # - то, что вы хотите.
%ProjectPath%/SecureStringsEasy.cs
источник
Я получил из этого ответа sclarke81 . Мне нравится его ответ, и я использую производную, но у sclarke81 есть ошибка. У меня нет репутации, поэтому я не могу комментировать. Проблема кажется достаточно маленькой, чтобы она не требовала другого ответа, и я мог ее отредактировать. Так я и сделал. Это было отклонено. Так что теперь у нас есть другой ответ.
sclarke81 Я надеюсь, что вы видите это (в конце концов):
должно быть:
И полный ответ с исправлением ошибки:
источник
Окончательное рабочее решение в соответствии с решением sclarke81 и исправлениями Джона Флаэрти:
источник
источник
BSTR
явно не освобождает , и это не объект .NET, поэтому сборщик мусора об этом тоже не позаботится. Сравните со stackoverflow.com/a/818709/103167, который был размещен 5 лет назад и не течет.Если вы используете
StringBuilder
вместо astring
, вы можете перезаписать фактическое значение в памяти, когда вы закончите. Таким образом, пароль не будет храниться в памяти, пока сборщик мусора не заберет его.источник