Что сделать, когда Вы не можете сохранить пароль как хеш

У меня есть программа, которая использует 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;
    }
}
8
задан Scott Chamberlain 16 February 2010 в 15:22
поделиться

3 ответа

Для немедленного отображения клавиатуры необходимо установить текстовое поле в качестве первого ответчика, используя следующую строку:

[textField becomeFirstResponder];

Можно поместить его в метод viewDidAppean: .

-121--1014947-

Riak работает под управлением Linux и позволяет динамически добавлять узлы

-121--1214775-

Вместо записи нового System.Text.ASCIIEncoding () следует написать System.Text.Encoding.ASCII .

Также вместо этого я рекомендую использовать UTF8.

Кроме этого, ваш код выглядит довольно хорошо.

2
ответ дан 5 December 2019 в 22:18
поделиться

Что касается соли, я бы сделал преобразование имени пользователя (хеш-значение), а не делился бы одной и той же солью для всех.

Для чего-то вроде этого я бы также поискал способ продлить существующий сеанс, а не сохранять пароль для создания новых сеансов.

4
ответ дан 5 December 2019 в 22:18
поделиться

Мне нравится подход Джоэла Кихорна.

Используйте значение, уникальное для компьютера пользователя, в качестве соли пароля.

Так что в каждом деплименте все будет по-разному; ).

ОБНОВЛЕНИЕ: идеи см. В этой ветке: How-To-Get-Unique-Machine-Signature

0
ответ дан 5 December 2019 в 22:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: