Я только что просматривал одну из статей Дэвида Хейдена о хешировании паролей пользователей .
На самом деле я не могу получить то, что он пытается достичь.
Вот его код:
private static string CreateSalt(int size)
{
//Generate a cryptographic random number.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
// Return a Base64 string representation of the random number.
return Convert.ToBase64String(buff);
}
private static string CreatePasswordHash(string pwd, string salt)
{
string saltAndPwd = String.Concat(pwd, salt);
string hashedPwd =
FormsAuthentication.HashPasswordForStoringInConfigFile(
saltAndPwd, "sha1");
return hashedPwd;
}
Есть ли другой метод C # для хеширования паролей и добавления соли к нему?
SHA1
это не криптографический класс, поэтому вы должны по крайней мере использоватьSHA256
, который выводит 256 бит или 32 байта. НО 256 бит НЕ легко конвертируются в base 64, потому что каждый символ base64 кодирует 6 бит, а 256 не делится полностью на 6. Таким образом, вам нужен общий знаменатель 6 (для base64) и 8 (для бит в байте) более 256 бит, что составляет 264 байта или 33 байта. TLDR: использовать 33.Ответы:
На самом деле это довольно странно с преобразованиями строк - которые провайдер членства делает, чтобы поместить их в конфигурационные файлы. Хэши и соли - это двоичные двоичные объекты, вам не нужно преобразовывать их в строки, если вы не хотите помещать их в текстовые файлы.
В моей книге « Начало безопасности ASP.NET» (о, наконец, оправдание для того, чтобы подтолкнуть книгу) я делаю следующее
Образование соли является примером в этом вопросе. Вы можете конвертировать текст в байтовые массивы, используя
Encoding.UTF8.GetBytes(string)
. Если вам необходимо преобразовать хеш в его строковое представление, вы можете использовать егоConvert.ToBase64String
иConvert.FromBase64String
для обратного преобразования.Вы должны заметить, что вы не можете использовать оператор равенства в байтовых массивах, он проверяет ссылки, и поэтому вы должны просто пройти через оба массива, проверяя каждый байт таким образом
Всегда используйте новую соль для каждого пароля. Соли не должны храниться в секрете и могут храниться вместе с самим хешем.
источник
return array1.Length == array2.Length && !array1.Where((t, i) => t != array2[i]).Any();
Что сказал Blowdart, но с немного меньшим количеством кода. Используйте Linq или
CopyTo
для объединения массивов.У Linq также есть простой способ сравнить ваши байтовые массивы.
Однако, прежде чем реализовывать что-либо из этого, проверьте этот пост . Для хеширования пароля вам может понадобиться медленный алгоритм хеширования, а не быстрый.
Для этого существует
Rfc2898DeriveBytes
класс, который работает медленно (и его можно сделать медленнее) и может ответить на вторую часть исходного вопроса в том смысле, что он может взять пароль и соль и вернуть хеш. Смотрите этот вопрос для получения дополнительной информации. Обратите внимание, Stack Exchange используетRfc2898DeriveBytes
для хеширования паролей (исходный код здесь ).источник
Я читал, что такие функции хеширования, как SHA256, не были предназначены для хранения паролей: https://patrickmn.com/security/storing-passwords-securely/#notpasswordhashes
Вместо этого были использованы адаптивные функции вывода ключей, такие как PBKDF2, bcrypt или scrypt. Вот основанный на PBKDF2 файл, который Microsoft написала для PasswordHasher в своей библиотеке Microsoft.AspNet.Identity:
Обратите внимание, что для этого требуется установленный пакет nuget Microsoft.AspNetCore.Cryptography.KeyDerivation , для которого требуется .NET Standard 2.0 (.NET 4.6.1 или выше). Для более ранних версий .NET см. Crypto Класс из библиотеки Microsoft System.Web.Helpers от Microsoft.
Обновление: ноябрь 2015 г.
Обновленный ответ для использования реализации из другой библиотеки Microsoft, в которой вместо PBKDF2-HMAC-SHA1 используется хеширование PBKDF2-HMAC-SHA1 (обратите внимание, что PBKDF2-HMAC-SHA1 по- прежнему безопасен, если iterCount достаточно высок). Вы можете проверить источник, из которого был скопирован упрощенный код, так как он фактически обрабатывает проверку и обновление хэшей, реализованных из предыдущего ответа, что полезно, если вам нужно увеличить iterCount в будущем.
источник
PBKDF2SubkeyLength
до 20 байт. Это естественный размер SHA1 и увеличение его сверх того, что замедляет защитника, не замедляя атакующего. 2) Я рекомендую увеличить количество итераций. Я рекомендую от 10 000 до 100 000 в зависимости от вашего бюджета производительности. 3) Сравнение с постоянным временем также не повредит, но не оказывает большого практического влияния.Соль используется для добавления дополнительного уровня сложности к хешу, чтобы сделать его более сложным для взлома.
Из статьи на Sitepoint :
В .NET нет метода, автоматически делающего это, поэтому вам придется воспользоваться решением выше.
источник
Я создал класс, который имеет следующий метод:
Подтвердить ввод
`
источник
Бах, это лучше! http://sourceforge.net/projects/pwdtknet/ и это лучше, потому что ..... он выполняет растягивание ключа и использует HMACSHA512 :)
источник
Я сделал библиотеку SimpleHashing.Net, чтобы облегчить процесс хеширования с помощью базовых классов, предоставляемых Microsoft. Обычного SHA на самом деле недостаточно для безопасного хранения паролей.
В библиотеке используется идея формата хэша от Bcrypt, но, поскольку нет официальной реализации MS, я предпочитаю использовать то, что доступно в фреймворке (например, PBKDF2), но это слишком сложно из коробки.
Это быстрый пример использования библиотеки:
источник
Вот как я это делаю .. Я создаю хэш и сохраняю его с помощью
ProtectedData
API:источник
Я прочитал все ответы и думаю, что достаточно, особенно статьи @Michael с медленным хешированием и @CodesInChaos хорошими комментариями, но я решил поделиться своим фрагментом кода для хеширования / проверки, который может быть полезен и не требует [ Microsoft.AspNet.Cryptography .KeyDerivation .
Пожалуйста, обратите внимание на функцию SlowEquals, которая так важна. Наконец, я надеюсь, что это поможет, и, пожалуйста, не стесняйтесь, советуйте мне о лучших подходах.
источник
Используйте
System.Web.Helpers.Crypto
пакет NuGet от Microsoft. Это автоматически добавляет соль к хешу.Вы хэш-пароль, как это:
var hash = Crypto.HashPassword("foo");
Вы подтверждаете пароль как это:
var verified = Crypto.VerifyHashedPassword(hash, "foo");
источник
Если вы не используете ядро asp.net или .net, в проектах> = .Net Standard 2.0 также есть простой способ.
Сначала вы можете установить желаемый размер хеша, соли и номера итерации, который связан с длительностью генерации хеша:
Для генерации хэша и соли пароля вы можете использовать что-то вроде этого:
Чтобы проверить, является ли пароль, введенный пользователем, действительным, вы можете проверить значения в вашей базе данных:
Следующий модульный тест показывает использование:
Microsoft Rfc2898DeriveBytes Source
источник
В ответ на эту часть исходного вопроса «Существует ли какой-либо другой метод C # для хеширования паролей», этого можно добиться с помощью ASP.NET Identity v3.0 https://www.nuget.org/packages/Microsoft.AspNet.Identity. EntityFramework / 3.0.0-RC1-конечная
источник
источник
источник