C # Password Encryption - PullRequest
       6

C # Password Encryption

2 голосов
/ 29 июня 2011

В сети я нашел некоторый код, который довольно хорошо работает для того, что я пытаюсь сделать.Мне нужно что-то, что зашифрует пароль, сохранит его в базе данных и получит с легкостью.Приведенный ниже код выполняет почти все, что я ищу.

        string UserName = txtUser.Text;
        string password = txtPass.Text;

        string encrKey = "keyvalue";
        byte[] byteKey = { };
        byte[] IV = {25, 47, 60, 88, 99, 106, 125, 139};
        byteKey = Encoding.UTF8.GetBytes(encrKey.Substring(0, 8));
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        byte[] inputArray = Encoding.UTF8.GetBytes(password);

        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byteKey, IV), CryptoStreamMode.Write);
        cs.Write(inputArray, 0, inputArray.Length);
        cs.FlushFinalBlock();
        password = Convert.ToBase64String(ms.ToArray());

        SqlCommand cmd = new SqlCommand("INSERT INTO USers (UserName, Password) VALUES (@UserName, @Password)", myConnection);
        cmd.CommandType = CommandType.Text;

        cmd.Parameters.AddWithValue("@UserName", UserName);
        cmd.Parameters.AddWithValue("@Password", password);

        SqlDataReader rdr = cmd.ExecuteReader();

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

System.Security.Cryptography.CryptographicException: указанный ключ не является допустимым размером для этого алгоритма.Ошибка генерируется в линии Cryptostream.

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

Ответы [ 5 ]

14 голосов
/ 29 июня 2011

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

Стандартным алгоритмом хэширования является SHA-1, который доступен в .NET.

Для еще большей безопасности вы используете «Соль» в хешировании.

Вы можете прочитать больше об этом здесь: Salting Your Password: Best Practices?

2 голосов
/ 29 июня 2011

Если вам нужно изменить шифрование, просто используйте класс ProtectedData: http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx

Если другие здесь верны, используйте соленый хеш, как в примере ниже. Следующее было взято из " Другой пример того, как хранить хэш соленого пароля "

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 < HashSize; i++)
            if (test[i] != _hash[i])
                return false;
        return true;
    }
}
1 голос
/ 17 августа 2011

Я предлагаю вам использовать bcrypt. исходный код доступен на http://code.google.com/p/bcryptnet/ скачать и использовать его. но прежде чем его использовать. прочитайте документацию и поймите, как это работает и почему bcrypt ... это важно.

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

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

надеюсь, это поможет вам. если вы найдете что-то интересное, пожалуйста, дайте мне знать, мир XD ~~

все, что я сказал неправильно, поправьте меня XD

1 голос
/ 29 июня 2011

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

0 голосов
/ 29 июня 2011

Попробуйте вместо этого:

var hash = Encoding.ASCII.GetBytes(password);
var sha1 = new SHA1CryptoServiceProvider();
var sha1hash = sha1.ComputeHash(hash);
var hashedPassword = Encoding.ASCII.GetString(sha1hash);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...