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, но имейте в виду, что он использует профили пользователей для своего использования ключа, и поэтому вы должны убедиться, что вы олицетворяете пользователя, который имеет профиль с нужным вам ключом. Это может или не может быть тривиальным и может или не может вызвать головные боли и проблемы с безопасностью.