C# Чтение обратно зашифрованных паролей

Я использую приведенный ниже код для сохранения пароля в реестре, как я могу преобразовать его обратно? Код ниже не мой, но хорошо шифрует.

Спасибо

using System.Security.Cryptography;

public static string EncodePasswordToBase64(string password)
{  byte[] bytes   = Encoding.Unicode.GetBytes(password);
   byte[] dst     = new byte[bytes.Length];
   byte[] inArray = HashAlgorithm.Create("SHA1").ComputeHash(dst);
   return Convert.ToBase64String(inArray);
}

11 ответов

SHA1 - это алгоритм хеширования, а не алгоритм шифрования. Алгоритм хеширования - это односторонняя функция, которая преобразует данные в хеш этих данных, но исходные данные не могут быть получены из хэша. Алгоритм шифрования является двусторонней функцией, которая преобразует данные в зашифрованные данные, и затем зашифрованные данные могут быть преобразованы обратно в исходные данные.

Чтобы надежно сохранить пароль, чтобы его можно было прочитать, используйте класс ProtectedData.

public static string ProtectPassword(string password)
{
    byte[] bytes = Encoding.Unicode.GetBytes(password);
    byte[] protectedPassword = ProtectedData.Protect(bytes, null, DataProtectionScope.CurrentUser);
    return Convert.ToBase64String(protectedPassword);
}

public static string UnprotectPassword(string protectedPassword)
{
    byte[] bytes = Convert.FromBase64String(protectedPassword);
    byte[] password = ProtectedData.Unprotect(bytes, null, DataProtectionScope.CurrentUser);
    return Encoding.Unicode.GetString(password);
}

Возьмите все, что пользователь вводит в качестве пароля, чтобы получить доступ к системе, зашифруйте его таким же образом, а затем сравните зашифрованные значения, это нормальный подход. Я почти уверен, что SHA1 является шифрованием с ловушкой, то есть не может быть отслежено.

Вы не

SHA1 - это хэш, а не шифрование. Это односторонняя операция; обратное преобразование невозможно.

(Хорошо, это не совсем верно; если у вас есть таблица возможных значений SHA1 и значений простого текста, радужная таблица, тогда вам может повезти)

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

Хорошо, я знаю, что это не отвечает на ваш конкретный вопрос, но почему вы хотите преобразовать его обратно?

Если это сравнение для обеспечения аутентификации, стандартный подход заключается в том, чтобы шифровать этот текст ТАКЖЕ и сравнивать сохраненный пароль с предоставленным паролем.

Это более безопасно, так как это означает, что оригинальный пароль никогда не нужно расшифровывать.

Чтобы использовать класс System.Security.Cryptography.ProtectedData, необходимо добавить ссылку на System.Security в свой проект.

(Щелкните правой кнопкой мыши папку "Ссылки", выберите "Добавить ссылку...", найдите System.Security на вкладке.NET)

Я думаю, что одним из пунктов использования хэшей является то, что они не могут быть вычислены обратно.

Как сказал кто-то другой, вычислите хеш из пароля пользователя и сравните с сохраненным значением хеша.

Хм, просто любопытно, но не вернет ли это одинаковый хеш для всех паролей одинаковой длины?

Я заметил недавнее добавление класса XMLEncryptedData. Является ли метод XMLEncryptedData более подходящим для шифрования данных в файл XML, чем метод DPAPI?

Используя приведенный выше собственный фрагмент кода, вы хотите вызвать этот метод, когда пользователь изначально выбирает пароль, но добавить к паролю то, что называется солью, где-то в строке пароля (обычно в начале или в конце). Затем, когда пользователь пытается аутентифицироваться позже, он вводит свой пароль, вы запускаете его вместе с хешем с помощью того же метода, и если два хеша равны, это статистически отличный шанс, что пароли равны и действительны.

При этом, как известно, SHA1 имеет слабые места, и вам следует выбрать более сильный алгоритм. Если вы хотите остаться в семье SHA, то SHA512 довольно хорош.

Вы хотите использовать шифрование, а не хэширование. SHA в порядке, но используйте для этого методы шифрования. Проблема с шифрованием всегда в том, где поставить ключ для него. Вы не упомянули, была ли это рабочая станция или сервер, на котором вы это делали. На сервере я считаю, что лучше использовать ACL для ограничения доступа к ключу reg. Администраторы обычно могут получить доступ к ключу шифрования в любом случае... вам нужно где-то доверять. На рабочей станции вы можете использовать шифрование и хранить ключ в коде или использовать сертификат и ограничить доступ к нему, по крайней мере, в корпоративной среде... не для продажи программного обеспечения).

Вы можете использовать класс ProtectedData, но имейте в виду, что он использует профили пользователей для своего использования ключа, и поэтому вы должны убедиться, что вы олицетворяете пользователя, который имеет профиль с нужным вам ключом. Это может или не может быть тривиальным и может или не может вызвать головные боли и проблемы с безопасностью.

Другие вопросы по тегам