У меня есть программа, которая использует System.DirectoryServices.AccountManagement.PrincipalContext
чтобы проверить, что информацией пользователь, вводимый в экран установки, является действительный пользователь на домене (сам компьютер не находится на домене) и делают некоторые операции на пользователях домена. Проблема, я не хочу, чтобы пользователь должен был ввести его пароль каждый раз, когда они запускают программу, таким образом, я хочу сохранить его, но я не чувствую себя комфортно, храня пароль как простой текст в их app.config файле. PrincipalContext нужен незашифрованный пароль, таким образом, я не могу сделать соленого хеша, как все рекомендуют для хранения пароля.
Это - то, что я сделал
const byte[] mySalt = //It's a secret to everybody.
[global::System.Configuration.UserScopedSettingAttribute()]
public global::System.Net.NetworkCredential ServerLogin
{
get
{
var tmp = ((global::System.Net.NetworkCredential)(this["ServerLogin"]));
if(tmp != null)
tmp.Password = new System.Text.ASCIIEncoding().GetString(ProtectedData.Unprotect(Convert.FromBase64String(tmp.Password), mySalt, DataProtectionScope.CurrentUser));
return tmp;
}
set
{
var tmp = value;
tmp.Password = Convert.ToBase64String(ProtectedData.Protect(new System.Text.ASCIIEncoding().GetBytes(tmp.Password), mySalt, DataProtectionScope.CurrentUser));
this["ServerLogin"] = value;
}
}
Действительно ли это было правильным поступком или является там лучшим путем?
РЕДАКТИРОВАНИЕ - Вот является обновленной версией на основе общих предложений
private MD5 md5 = MD5.Create();
[global::System.Configuration.UserScopedSettingAttribute()]
public global::System.Net.NetworkCredential ServerLogin
{
get
{
var tmp = ((global::System.Net.NetworkCredential)(this["ServerLogin"]));
if(tmp != null)
tmp.Password = System.Text.Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(tmp.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp.UserName.ToUpper())), DataProtectionScope.CurrentUser));
return tmp;
}
set
{
var tmp = value;
tmp.Password = Convert.ToBase64String(ProtectedData.Protect(System.Text.Encoding.UTF8.GetBytes(tmp.Password), md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(tmp.UserName.ToUpper())), DataProtectionScope.CurrentUser));
this["ServerLogin"] = tmp;
}
}
Для немедленного отображения клавиатуры необходимо установить текстовое поле в качестве первого ответчика, используя следующую строку:
[textField becomeFirstResponder];
Можно поместить его в метод viewDidAppean:
.
Riak работает под управлением Linux и позволяет динамически добавлять узлы
-121--1214775- Вместо записи нового System.Text.ASCIIEncoding ()
следует написать System.Text.Encoding.ASCII
.
Также вместо этого я рекомендую использовать UTF8.
Кроме этого, ваш код выглядит довольно хорошо.
Что касается соли, я бы сделал преобразование имени пользователя (хеш-значение), а не делился бы одной и той же солью для всех.
Для чего-то вроде этого я бы также поискал способ продлить существующий сеанс, а не сохранять пароль для создания новых сеансов.
Мне нравится подход Джоэла Кихорна.
Используйте значение, уникальное для компьютера пользователя, в качестве соли пароля.
Так что в каждом деплименте все будет по-разному; ).
ОБНОВЛЕНИЕ: идеи см. В этой ветке: How-To-Get-Unique-Machine-Signature