String hash di c #

92

Saya mengalami masalah saat mencoba memasukkan string hash c#.

Saya sudah mencoba beberapa situs web, tetapi kebanyakan dari mereka menggunakan file untuk mendapatkan hash. Yang lain untuk string agak terlalu rumit. Saya menemukan contoh untuk otentikasi Windows untuk web seperti ini:

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

Saya perlu menggunakan hash untuk membuat string yang berisi nama file lebih aman. Bagaimana saya bisa melakukan itu?

Contoh:

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

Haruskah saya menggunakan algoritme hashing lain dan bukan "md5"?

Edy Cu
sumber

Jawaban:

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();
}

catatan tambahan

  • Karena MD5 dan SHA1 adalah algoritme yang usang dan tidak aman , solusi ini menggunakan SHA256. Alternatifnya, Anda dapat menggunakan BCrypt atau Scrypt seperti yang ditunjukkan di komentar.
  • Juga, pertimbangkan untuk " mengasinkan " hash Anda dan menggunakan algoritme kriptografi yang telah terbukti, seperti yang ditunjukkan dalam komentar.
Dmitry Polomoshnov
sumber
46
JANGAN GUNAKAN MD5 ATAU SHA1 , itu adalah algoritme yang usang dan tidak aman. Gunakan SHA256 paling tidak atau bahkan lebih baik gunakan BCrypt atau Scrypt.
Muhammad Rehan Saeed
1
Lihat contoh penggunaan SCrypt ini: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
6
@Muh Ini dapat dengan mudah digunakan untuk checksum, karena jauh lebih cepat dari SHA512. Tapi memang untuk menyimpan Passwords itu tidak recommended, mana yang benar.
LuckyLikey
6
Apa b.ToString("X2")maksudnya ini ?
Bilal Fazlani
1
@BilalFazlani lihat stackoverflow.com/questions/20750062/…
Hezi
60

Cara tercepat, untuk mendapatkan string hash untuk tujuan penyimpanan kata sandi, adalah kode berikut:

    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);
        }
    }

Catatan:

  • jika metode sering dipanggil, pembuatan shavariabel harus direfraktorisasi menjadi bidang kelas;
  • keluaran disajikan sebagai string hex yang dikodekan;
andrew.fox
sumber
SHA1Managedkelas tidak terlalu mahal. itu memakan sekitar 130 byte dan menginisialisasinya ke beberapa nilai statis, tapi itu saja. jadi seharusnya tidak ada masalah kinerja dalam banyak kasus.
Earth Engine
1
Juga SHA1Managedadalah IDisposablesehingga membutuhkan untuk membungkus penggunaannya menjadi usingblok.
Earth Engine
DisposeMetode tujuan adalah untuk menghapus buffer internal. Kegagalan untuk melakukannya akan berisiko mengalami serangan memori.
Mesin Bumi
3
@MuhammadRehanSaeed ketika saya bilang SHA1Managedtidak mahal maksud saya pembuatannya tidak. Selain itu, algoritma hashing tidak perlu mahal. Ini hanya harus (sangat) mahal ketika Anda ingin menemukan tabrakan.
Mesin Bumi
1
@KingFisher - tidak mungkin! Hash adalah fungsi satu arah, informasi hilang. Jika Anda perlu mendekripsi, Anda perlu menggunakan metode enkripsi bukan hashing. BTW, mengenkripsi kata sandi adalah praktik yang buruk.
andrew.fox
8

Saya tidak benar-benar memahami cakupan penuh pertanyaan Anda, tetapi jika yang Anda butuhkan hanyalah hash string, maka sangat mudah untuk mendapatkannya.

Cukup gunakan metode GetHashCode.

Seperti ini:

string hash = username.GetHashCode();
Cyril Gupta
sumber
1
Ya, itulah yang dicari. Tapi itu kode kesalahan besar. Tampilkan tulisan seperti int hash = "username" .GetHasCode ();
Edy Cu
3
Mengapa Anda memasukkan nama pengguna dalam tanda kutip ganda? Itu akan mendapatkan hash dari kata 'username' dan sekarang apa yang ada di variabel username.
Cyril Gupta
15
jangan menyimpan nilai dari GetHashCode, ini berbeda untuk 32x dan 64x
Slava
13
Ini adalah cara yang buruk untuk membuat hash kata sandi. Dengan GetHashCode () Anda tidak dapat berasumsi bahwa nomor yang sama akan dihasilkan dari komputer yang berbeda. Gunakan metode hash Sha1 atau sesuatu (saya akan memposting contoh nanti)
andrew.fox
2
Perlu diperhatikan bahwa GetHashCodeini bukanlah algoritme hashing yang aman secara kriptografis. Gunakan SHA256 setidaknya atau bahkan lebih baik gunakan BCrypt atau Scrypt untuk algoritma yang aman.
Muhammad Rehan Saeed
5

Saya pikir yang Anda cari bukanlah hashing, tetapi enkripsi. Dengan hashing, Anda tidak akan dapat mengambil nama file asli dari variabel "hash". Dengan enkripsi Anda bisa, dan itu aman.

Lihat AES di ASP.NET dengan VB.NET untuk informasi selengkapnya tentang enkripsi di .NET.

Pieter van Ginkel
sumber
ya, saya pikir itu enkripsi, tetapi saya hanya ingin membandingkan hash hasil. Setelah halaman redirect.
Edy Cu
Dengan apa Anda ingin membandingkan nama file yang di-hash?
Pieter van Ginkel
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();
    }
Soufiane Neffar
sumber
3
JANGAN GUNAKAN SHA1 dari tautan ini, SHA1 adalah algoritme yang usang dan tidak aman. Gunakan SHA256 paling tidak atau bahkan lebih baik gunakan BCrypt atau Scrypt.
Muhammad Rehan Saeed
Lihat contoh penggunaan SCrypt ini: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed
1

Jika performa bukan masalah utama, Anda juga dapat menggunakan salah satu metode berikut:
(Jika Anda ingin string hash menggunakan huruf besar, ganti "x2"dengan "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")));
}

atau:

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();
}
Babak
sumber
0

Cara terpendek dan tercepat yang pernah ada. Hanya 1 baris!

    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);
Erçin Dedeoğlu
sumber