Хэш-пароль в C#? Осуществляется/PBKDF2 с

Я посмотрел msdn и другие ресурсы о том, как это сделать, но у меня не было четких решений. Это лучшее, что я нашел http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx?Redirected=true

Я хотел бы хэшировать пароли В C#, используя bcrypt или PBKDF2 (который, похоже, связан с bcrypt). Мне нравится экспериментировать с тем, сколько раундов требуется для моего компьютера, чтобы хэшировать пароль. Однако все, кажется, о шифрование, пока все говорят о хэшировании. Я не могу понять. Как хэшировать пароль? Это больше похоже на PBKDF2 (Rfc2898?) является генератором случайных чисел, и я использую GetBytes(сумма), чтобы выбрать, насколько велик мой размер хэша.

Я в замешательстве. Как именно я хеширую пароль с помощью bcrypt / PBKDF?

7 ответов


PBKDF2 с

Вы были очень близки на самом деле. Ссылка, которую вы дали показывает вам, как вы можете называть Rfc2898DeriveBytes функция для получения результатов хэша PBKDF2. Однако вы были сбиты с толку тем фактом, что пример использовал производный ключ для целей шифрования (первоначальная мотивация для PBKDF1 и 2 заключалась в создании "ключевых" функций деривации, подходящих для использования в качестве ключей шифрования). Конечно, мы не хотим использовать вывод для шифрования, а хэш собственный.

вы можете попробовать SimpleCrypto.Net библиотека написана именно для этой цели, если вы хотите PBKDF2. Если ты ... --9-->тут, вы можете видеть, что это на самом деле просто тонкая обертка вокруг (вы догадались) Rfc2898DeriveBytes.

BCrypt

вы можете попробовать реализацию C# с именем (что еще)BCrypt.NET Если вы хотите поэкспериментировать с этим вариант.

отказ от ответственности: я не использовал и не тестировал ни одну из библиотек, с которыми я связан... YMMV


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

вам нужно прочитать документация и theory1 theory2 и тогда некоторые или вы можете быть открыты для лазеек безопасности. Безопасность-очень большая тема! Покупатель Остерегайтесь!

добавить пакет NuGet BCrypt.Net к решение

const int WorkFactor = 14;
var HashedPassword = BCrypt.Net.BCrypt.HashPassword(Password, WorkFactor); 

вы должны настроить WorkFactor к чему уместно посмотреть обсуждения. Его функции lоg2

" номер log2, поэтому каждый раз, когда компьютеры удваивают скорость, добавьте 1 к номеру по умолчанию."

затем вы храните хэш пароля в БД как passwordFromLocalDB и проверить входящий password такой:

if (BCrypt.Net.BCrypt.Verify(password, passwordFromLocalDB) == true)

Удачи!


ранее в этом году я рассматривал то же самое для создания хэшей для наших ASP.NET проект веб-форм, я хотел сделать это так же, как проекты MVC делают это из коробки.

я наткнулся на этот вопрос =>ASP.NET Identity default Password Hasher, как он работает и является ли он безопасным? Затем я нашел источник с методом ByteArraysEqual здесь => http://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.Core/2.0.0-rtm-140327/Release/Default/Microsoft.AspNet.Identity.Core/Microsoft.AspNet.Identity.Core/Crypto.cs?ImageName=Microsoft.AspNet.Identity.Core


для PBKDF2 вы можете использовать System.Безопасность.Криптография.Rfc2898DeriveBytes.

см. MSDN здесь: http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx


PBKDF2 использует HMACSHA1, если вы хотите более современное и настраиваемое решение, вы должны посмотреть на этот API, используя HMACSHA256 или 512 с ключом растяжения так же, как PBKDF2

https://sourceforge.net/projects/pwdtknet/

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


PBKDF2 с

в Примере в http://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes.aspx, Когда вы доберетесь до строки " Rfc2898DeriveBytes k1 = новый Rfc2898DeriveBytes(pwd1, salt1, myIterations);", " К1 " - это хэш. Причина, по которой пример предназначен для шифрования, заключается в том, что Rfc2898DeriveBytes изначально был разработан для создания ключей шифрования.

Если вы не предоставляете соль, Rfc2898DeriveBytes создаст ее самостоятельно, но я делаю не знаю, делает ли RNGCryptoServiceProvider лучшую работу криптографически случайной.

согласно OWASP (https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2), основное использование SHA1 Rfc2898DeriveBytes означает, что он хорош только для хэшей длиной до 160 бит. Если вы создадите более длинный хэш, злоумышленнику все равно придется беспокоиться только о первых 160 битах, но вы сделали хэширование/аутентификацию пароля более дорогостоящей для себя без выгоды.

вот пример кода для хэширования паролей Rfc2898DeriveBytes (хранить хэш, соль и итерации в БД):

public class Rfc2898PasswordEncoder
{
    private int _byteLength = 160 / 8; // 160 bit hash length

    public class EncodedPassword
    {
        public byte[] Hash { get; set; }
        public byte[] Salt { get; set; }
        public int Iterations { get; set; }
    }

    public EncodedPassword EncodePassword(string password, int iterations)
    {
        var populatedPassword = new EncodedPassword
        {
            Salt = CreateSalt(),
            Iterations = iterations
        };

        // Add Hash
        populatedPassword.Hash = CreateHash(password, populatedPassword.Salt, iterations);

        return populatedPassword;
    }

    public bool ValidatePassword(string password, EncodedPassword encodedPassword)
    {
        // Create Hash
        var testHash = CreateHash(password, encodedPassword.Salt, encodedPassword.Iterations);

        return testHash == encodedPassword.Hash;
    }

    public byte[] CreateSalt()
    {
        var salt = new byte[_byteLength]; // Salt should be same length as hash

        using (var saltGenerator = new RNGCryptoServiceProvider())
        {
            saltGenerator.GetBytes(salt);
        }

        return salt;
    }

    private byte[] CreateHash(string password, byte[] salt, long iterations)
    {
        byte[] hash;
        using (var hashGenerator = new Rfc2898DeriveBytes(password, salt, (int)iterations))
        {
            hash = hashGenerator.GetBytes(_byteLength);
        }

        return hash;
    }
} 

меня интересовали ответы, которые не включали никаких библиотек.

Я читал эту статью https://crackstation.net/hashing-security.htm который связывает реализацию на разных языках C# среди них, которые я тоже свяжу здесь

https://github.com/defuse/password-hashing/blob/master/PasswordStorage.cs

интересно, что он использует Rfc2898DeriveBytes, как упоминалось несколько раз здесь.

private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes){
    using (var pbkdf2 = new Rfc2898DeriveBytes(password, salt)) {
        pbkdf2.IterationCount = iterations;
        return pbkdf2.GetBytes(outputBytes);
    }
}