Я должен сохранить соль где-нибудь при хешировании пароля? - PullRequest
1 голос
/ 15 февраля 2011
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Sergio");
        Console.WriteLine(HashString("Sergio"));
        Console.WriteLine(HashString("Sergio"));
        Console.WriteLine(HashString("Sergio"));
        Console.ReadKey();
    }

    public static string HashString(string value)
    {
        int minSaltSize = 4;
        int maxSaltSize = 8;
        Random random = new Random();
        int saltSize = random.Next(minSaltSize, maxSaltSize);
        byte[] saltBytes = new byte[saltSize];

        RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
        rng.GetNonZeroBytes(saltBytes);

        //Convert the string value into a byte array.
        UTF8Encoding utf8Encoder = new UTF8Encoding();
        byte[] plainTextBytes = utf8Encoder.GetBytes(value);

        //Allocate an array to hold the text bytes and the salt bytes.
        byte[] plainTextWithSaltBytes = new Byte[saltBytes.Length + plainTextBytes.Length];

        for (int i = 0; i < plainTextBytes.Length; i++)
        {
            plainTextWithSaltBytes[i] = plainTextBytes[i];
        }

        for (int i = 0; i < saltBytes.Length; i++)
        {
            plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
        }

        HashAlgorithm hash = new SHA256Managed();
        byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes);
        string hashedValue = Convert.ToBase64String(hashBytes);
        return hashedValue;
    }
}

Результатом моего кода является то, что хеширование "Sergio" каждый раз отличаетсяЭто вызвано случайным фактором, включенным в соль.У меня вопрос, я должен где-нибудь сохранить соль?Или я определяю постоянную соль в моем коде?

Спасибо!

Ответы [ 5 ]

1 голос
/ 15 февраля 2011

Вы можете использовать этот класс для создания соли / хеша и объединения двух значений:

public sealed class PasswordHash
{
    const int SaltSize = 16, HashSize = 20, HashIter = 10000;
    readonly byte[] _salt, _hash;
    public PasswordHash(string password)
    {
        new RNGCryptoServiceProvider().GetBytes(_salt = new byte[SaltSize]);
        _hash = new Rfc2898DeriveBytes(password, _salt, HashIter).GetBytes(HashSize);
    }
    public PasswordHash(byte[] hashBytes)
    {
        Array.Copy(hashBytes, 0, _salt = new byte[SaltSize], 0, SaltSize);
        Array.Copy(hashBytes, SaltSize, _hash = new byte[HashSize], 0, HashSize);
    }
    public PasswordHash(byte[] salt, byte[] hash)
    {
        Array.Copy(salt, 0, _salt = new byte[SaltSize], 0, SaltSize);
        Array.Copy(hash, 0, _hash = new byte[HashSize], 0, HashSize);
    }
    public byte[] ToArray()
    {
        byte[] hashBytes = new byte[SaltSize + HashSize];
        Array.Copy(_salt, 0, hashBytes, 0, SaltSize);
        Array.Copy(_hash, 0, hashBytes, SaltSize, HashSize);
        return hashBytes;
    }
    public byte[] Salt { get { return (byte[])_salt.Clone(); } }
    public byte[] Hash { get { return (byte[])_hash.Clone(); } }
    public bool Verify(string password)
    {
        byte[] test = new Rfc2898DeriveBytes(password, _salt, HashIter).GetBytes(HashSize);
        for (int i = 0; i &lt; HashSize; i++)
            if (test[i] != _hash[i])
                return false;
        return true;
    }
}

http://csharptest.net/?p=470

1 голос
/ 15 февраля 2011

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

1 голос
/ 15 февраля 2011

Если вы используете разные соли, вам нужно будет сохранить как хешированный пароль, так и соль в БД. Вы также можете сохранить соль в файле app.config / web.config, если это та же соль.

0 голосов
/ 15 февраля 2011

Я был поклонником GUID для соли и SHA512 для хэша.Время ЦП не является проблемой, так как оно только во время аутентификации.

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

сохраненный пароль = хеш (соль +пароль)

если вы забудете соль, вы не сможете сравнить значения.

0 голосов
/ 15 февраля 2011

Absolutly. Всегда используйте новую соль для хешированного пароля, а не константу. Было бы небезопасно иметь одинаковую соль для всех паролей ( защита от радужных таблиц ).

Сохраните его где-нибудь, например в базе данных в дополнительном поле или даже в том же поле с хешированным паролем (например, bcrypt делает это похоже), если вы не можете добавить дополнительное поле в логику своей базы данных.

Но всегда используйте новую случайную соль для пароля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...