Строка хэша в c #

92

У меня проблема при попытке ввести хеш-строку c#.

Я уже пробовал несколько веб-сайтов, но большинство из них используют файлы для получения хеша. Другие, предназначенные для струнных, слишком сложны. Я нашел такие примеры проверки подлинности Windows в Интернете:

FormsAuthentication.HashPasswordForStoringInConfigFile(tbxPassword.Text.Trim(), "md5")

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

Пример:

string file  = "username";
string hash = ??????(username); 

Должен ли я использовать другой алгоритм хеширования, а не «md5»?

Эди Ку
источник

Ответы:

184
using System.Security.Cryptography;

public static byte[] GetHash(string inputString)
{
    using (HashAlgorithm algorithm = SHA256.Create())
        return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

public static string GetHashString(string inputString)
{
    StringBuilder sb = new StringBuilder();
    foreach (byte b in GetHash(inputString))
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}

Дополнительные примечания

  • Поскольку MD5 и SHA1 являются устаревшими и небезопасными алгоритмами, в этом решении используется SHA256. Кроме того , вы можете использовать Bcrypt или Scrypt , как указано в комментариях.
  • Кроме того, подумайте о « солении » ваших хэшей и используйте проверенные криптографические алгоритмы, как указано в комментариях.
Дмитрий Поломошнов
источник
46
НЕ ИСПОЛЬЗУЙТЕ MD5 ИЛИ SHA1 , это устаревшие и небезопасные алгоритмы. Используйте как минимум SHA256, а еще лучше - BCrypt или Scrypt.
Мухаммад Рехан Саид
1
См. Этот пример использования SCrypt: stackoverflow.com/questions/20042977/…
Мухаммад Рехан Саид,
6
@Muh Его легко использовать для контрольных сумм, потому что он намного быстрее, чем SHA512. Но действительно хранить пароли не рекомендуется, и это правильно.
LuckyLikey
6
Что это b.ToString("X2")значит?
Билал Фазлани 05
1
@BilalFazlani см stackoverflow.com/questions/20750062/...
HEZI
60

Самый быстрый способ получить хеш-строку для хранения паролей - это следующий код:

    internal static string GetStringSha256Hash(string text)
    {
        if (String.IsNullOrEmpty(text))
            return String.Empty;

        using (var sha = new System.Security.Cryptography.SHA256Managed())
        {
            byte[] textData = System.Text.Encoding.UTF8.GetBytes(text);
            byte[] hash = sha.ComputeHash(textData);
            return BitConverter.ToString(hash).Replace("-", String.Empty);
        }
    }

Примечания:

  • если метод вызывается часто, создание shaпеременной должно быть преобразовано в поле класса;
  • вывод представлен в виде закодированной шестнадцатеричной строки;
andrew.fox
источник
SHA1Managedкласс не очень затратный. он потребляет около 130 байт и инициализирует их некоторым статическим значением, но это все. поэтому в большинстве случаев проблем с производительностью быть не должно.
Earth Engine
1
Также SHA1Managedесть IDisposableи, следовательно, требуется обернуть его использование в usingблок.
Earth Engine
Целевой Disposeметод - очистить внутренний буфер. В противном случае существует риск атаки на память.
Earth Engine
3
@MuhammadRehanSaeed, когда я сказал, что SHA1Managedэто не дорого, я имею в виду, что его создание - нет. Кроме того, алгоритм хеширования не требует больших затрат. Это должно быть (чрезвычайно) дорогостоящим только тогда, когда вы хотите найти столкновение.
Earth Engine
1
@King_Fisher - это невозможно! Хеширование - это односторонняя функция, информация теряется. Если вам нужно расшифровать, вам нужно использовать метод шифрования, а не хеширование. Кстати, шифрование паролей - плохая практика.
andrew.fox
8

Я не совсем понимаю весь объем вашего вопроса, но если все, что вам нужно, это хеш строки, то это очень легко получить.

Просто используйте метод GetHashCode.

Как это:

string hash = username.GetHashCode();
Кирилл Гупта
источник
1
Да, именно то, что искал. Но этот код - большая ошибка. Показать запись типа int hash = "username" .GetHasCode ();
Edy Cu
3
Почему вы заключили имя пользователя в двойные кавычки? Это получит хэш слова «имя пользователя», а теперь то, что находится в переменной имени пользователя.
Сирил Гупта
15
не храните значения из GetHashCode, он отличается для 32x и 64x
Слава
13
Это плохой способ создания хэша пароля. Используя GetHashCode (), вы не можете предполагать, что один и тот же номер будет сгенерирован на разных компьютерах. Используйте метод хеширования Sha1 или что-то в этом роде (пример я
опубликую
2
Следует отметить, что GetHashCodeэто не криптографически безопасный алгоритм хеширования. Используйте как минимум SHA256, а еще лучше используйте BCrypt или Scrypt для безопасного алгоритма.
Мухаммад Рехан Саид
5

Я думаю, что вам нужно не хеширование, а шифрование. С помощью хеширования вы не сможете получить исходное имя файла из переменной "hash". С шифрованием вы можете, и это безопасно.

См. AES в ASP.NET с VB.NET для получения дополнительной информации о шифровании в .NET.

Питер ван Гинкель
источник
да, я думаю, это шифрование, но я просто хочу сравнить хэш результата. После перенаправления страницы.
Edy Cu
С чем вы хотите сравнить хешированное имя файла?
Питер ван Гинкель
1
//Secure & Encrypte Data
    public static string HashSHA1(string value)
    {
        var sha1 = SHA1.Create();
        var inputBytes = Encoding.ASCII.GetBytes(value);
        var hash = sha1.ComputeHash(inputBytes);
        var sb = new StringBuilder();
        for (var i = 0; i < hash.Length; i++)
        {
            sb.Append(hash[i].ToString("X2"));
        }
        return sb.ToString();
    }
Суфиан Неффар
источник
3
НЕ ИСПОЛЬЗУЙТЕ SHA1 из этой ссылки, SHA1 - устаревший и небезопасный алгоритм. Используйте как минимум SHA256, а еще лучше - BCrypt или Scrypt.
Мухаммад Рехан Саид
См. Этот пример использования SCrypt: stackoverflow.com/questions/20042977/…
Мухаммад Рехан Саид,
1

Если производительность не является серьезной проблемой, вы также можете использовать любой из этих методов:
(Если вы хотите, чтобы хеш-строка была в верхнем регистре, замените ее "x2"на "X2".)

public static string SHA256ToString(string s) 
{
    using (var alg = SHA256.Create())
        return string.Join(null, alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Select(x => x.ToString("x2")));
}

или:

public static string SHA256ToString(string s)
{            
    using (var alg = SHA256.Create())
        return alg.ComputeHash(Encoding.UTF8.GetBytes(s)).Aggregate(new StringBuilder(), (sb, x) => sb.Append(x.ToString("x2"))).ToString();
}
Бабак
источник
0

Самый короткий и быстрый способ. Всего 1 строчка!

    public static string StringSha256Hash(string text) =>
        string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
Эрчин Дедеоглу
источник