Відповіді:
Ви цього не робите. Вся причина використання об’єкта 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');
12345
це така річ, яку ідіот має у своєму багажі!"
*****
AppendChar
не виконується до часу запуску, тож ці символи все ще можна прочитати з IL, правда? Можливо, якась затуманення часу компіляції також допоможе ... тобто, якщо ви жорстко кодуєте паролі.
Існує також інший спосіб перетворення між SecureString
і String
.
1. Рядок для SecureString
SecureString theSecureString = new NetworkCredential("", "myPass").SecurePassword;
2. SecureString для String
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
a 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;
}
Array.Clear