Как конвертировать String
в SecureString
?
Как конвертировать String
в SecureString
?
Ответы:
Вы этого не сделаете. Вся причина использования объекта SecureString состоит в том, чтобы избежать создания строкового объекта (который загружается в память и хранится там в виде открытого текста до сборки мусора). Однако вы можете добавлять символы в SecureString, добавляя их.
var s = new SecureString();
s.AppendChar('d');
s.AppendChar('u');
s.AppendChar('m');
s.AppendChar('b');
s.AppendChar('p');
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('d');
*****
AppendChar
не выполняется до времени выполнения, поэтому эти символы все еще можно прочитать из IL, верно? Может быть, некоторая обфускация во время компиляции тоже поможет ... то есть, если вы жестко кодируете пароли.
Существует также другой способ преобразования между SecureString
и String
.
1. Строка в SecureString
SecureString theSecureString = new NetworkCredential("", "myPass").SecurePassword;
2. SecureString в строку
string theString = new NetworkCredential("", theSecureString).Password;
Вот ссылка
SecureString
если ваш код создает string
объект со значением, которое вы хотите защитить. Цель SecureString
состоит в том, чтобы избежать попадания строки в управляемую память, чтобы злоумышленник, исследующий эту память, мог обнаружить значение, которое вы хотите скрыть. Поскольку NetworkCredential
вызываемый вами конструктор требует строки, это не выход ... Конечно, ваш код - это простой способ преобразования в SecureString и обратно, но его использование делает ваш код таким же безопасным, как использование простогоstring
SecureString
при работе с некоторыми библиотеками. И давайте будем честными: если кто-то активно сканирует память вашего приложения, значит, вы уже проиграли. Даже если вы правильно использовали SecureString, чего я никогда не видел, вам придется извлечь другие ценные данные.
метод ниже помогает преобразовать строку в безопасную строку
private SecureString ConvertToSecureString(string password)
{
if (password == null)
throw new ArgumentNullException("password");
var securePassword = new SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
securePassword.MakeReadOnly();
return securePassword;
}
Вот дешевый трюк с linq.
SecureString sec = new SecureString();
string pwd = "abc123"; /* Not Secure! */
pwd.ToCharArray().ToList().ForEach(sec.AppendChar);
/* and now : seal the deal */
sec.MakeReadOnly();
Я выкину это там. Зачем?
Вы не можете просто изменить все свои строки на защищенные, и вдруг ваше приложение станет «безопасным». Защищенная строка предназначена для хранения строки в зашифрованном виде как можно дольше и дешифрования только в течение очень короткого периода времени, стирая память после выполнения операции с ней.
Я бы рискнул сказать, что у вас могут возникнуть проблемы на уровне дизайна, прежде чем беспокоиться о защите строк приложения. Сообщите нам больше информации о том, что вы пытаетесь сделать, и мы сможем помочь лучше.
нет причудливого linq, не добавляя все символы вручную, просто и просто:
var str = "foo";
var sc = new SecureString();
foreach(char c in str) sc.appendChar(c);
var sc = new SecureString(); foreach(char c in "foo") sc.appendChar(c);
Я просто хочу указать всем, кто говорит: «Дело не в этом SecureString
», что многие из людей, задающих этот вопрос, могут быть в приложении, где по какой-либо причине, оправданной или нет, они не особенно обеспокоены тем, что временная копия пароля находится в куче как строка с поддержкой GC, но они должны использовать API, который принимает толькоSecureString
объекты. Итак, у вас есть приложение, в котором вам все равнонаходится ли пароль в куче, возможно, он предназначен только для внутреннего использования, а пароль существует только потому, что он требуется базовыми сетевыми протоколами, и вы обнаружите, что эта строка, в которой хранится пароль, не может использоваться, например, для настройки удаленной оболочки PowerShell Пространство выполнения - но нет простого и понятного однострочника для создания того, SecureString
что вам нужно. Это небольшое неудобство - но , вероятно , стоит того , чтобы гарантировать , что приложения , которые действительно делают нужно SecureString
делать не искушать автор к использованию System.String
или System.Char[]
посредникам. :-)
Если вы хотите , чтобы сжать преобразование string
к SecureString
в LINQ
заявлении можно выразить следующим образом :
var plain = "The quick brown fox jumps over the lazy dog";
var secure = plain
.ToCharArray()
.Aggregate( new SecureString()
, (s, c) => { s.AppendChar(c); return s; }
, (s) => { s.MakeReadOnly(); return s; }
);
Однако имейте в виду, что использование LINQ
не повышает безопасность этого решения. Он страдает тем же недостатком, что и любое преобразование из string
в SecureString
. Пока оригинал string
остается в памяти, данные уязвимы.
При этом то, что может предложить приведенный выше оператор, заключается в том, чтобы объединить создание SecureString
, его инициализацию данными и, наконец, блокировку его от модификации.
Следующие 2 расширения должны помочь:
Для char
массива
public static SecureString ToSecureString(this char[] _self)
{
SecureString knox = new SecureString();
foreach (char c in _self)
{
knox.AppendChar(c);
}
return knox;
}
И для string
public static SecureString ToSecureString(this string _self)
{
SecureString knox = new SecureString();
char[] chars = _self.ToCharArray();
foreach (char c in chars)
{
knox.AppendChar(c);
}
return knox;
}
Спасибо Джону Дэггу за AppendChar
рекомендацию.
вы можете использовать этот простой скрипт
private SecureString SecureStringConverter(string pass)
{
SecureString ret = new SecureString();
foreach (char chr in pass.ToCharArray())
ret.AppendChar(chr);
return ret;
}
12345
... такие вещи у идиота в багаже!»