C # 'ta karma dizesi


92

Bir hash dizesi almaya çalışırken sorun yaşıyorum c#.

Zaten birkaç web sitesini denedim, ancak çoğu hash'i almak için dosyaları kullanıyor. Dizeler için olan diğerleri biraz fazla karmaşıktır. Web için Windows kimlik doğrulaması için aşağıdaki gibi örnekler buldum:

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

Dosya adı içeren bir dizeyi daha güvenli hale getirmek için bir karma kullanmam gerekiyor. Bunu nasıl yapabilirim?

Misal:

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

Başka bir hash algoritması kullanmalı mıyım, "md5" değil mi?

Yanıtlar:


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

ek Notlar

  • MD5 ve SHA1 eski ve güvenli olmayan algoritmalar olduğundan, bu çözüm SHA256'yı kullanır. Alternatif olarak, yorumlarda belirtildiği gibi BCrypt veya Scrypt'i kullanabilirsiniz .
  • Ayrıca, " tuzlamayı karmalarınızı " ve yorumlarda belirtildiği gibi, kanıtlanmış şifreleme algoritmaları kullanın.

46
MD5 VEYA SHA1'i KULLANMAYIN , bunlar eski ve güvenli olmayan algoritmalardır. En azından SHA256'yı kullanın veya daha iyisi BCrypt veya Scrypt kullanın.
Muhammad Rehan Saeed

1
SCrypt kullanımıyla ilgili şu örneğe bakın: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed

6
@Muh SHA512'den çok daha hızlı olduğu için sağlama toplamları için kolayca kullanılabilir. Ama aslında Şifreleri saklamak tavsiye edilmez, ki bu doğru.
LuckyLikey

6
Bu ne anlama b.ToString("X2")geliyor?
Bilal Fazlani


60

Parola saklama amacıyla bir karma dizesi almanın en hızlı yolu aşağıdaki koddur:

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

Uyarılar:

  • yöntem sık sık çağrılıyorsa, shadeğişkenin oluşturulması bir sınıf alanına yeniden düzenlenmelidir;
  • çıktı kodlanmış onaltılık dizge olarak sunulur;

SHA1Managedsınıf çok maliyetli değil. yaklaşık 130 bayt tüketir ve bunları statik bir değerle başlatır, ama hepsi bu. bu nedenle çoğu durumda bir performans sorunu olmamalıdır.
Earth Engine

1
Ayrıca SHA1Managedolduğunu IDisposableve böylece içine kullanımını tamamlamayı gerektirir usingbloğun.
Earth Engine

Amaç Disposeyöntem, dahili tamponu temizlemektir. Bunu yapmamak, hafıza saldırısı riski taşır.
Earth Engine

3
@MuhammadRehanSaeed dediğimde SHA1Managedpahalı değil, yani yaratılışı değil. Ayrıca, bir hash algoritması maliyetli olmak zorunda değildir. Sadece bir çarpışma bulmak istediğinizde (son derece) maliyetli olması gerekir.
Earth Engine

1
@King_Fisher - bu imkansız! Hash tek yönlü bir işlevdir, bilgi kaybolur. Şifresini çözmeniz gerekirse, hashing yerine şifreleme yöntemini kullanmanız gerekir. BTW, şifreleri şifrelemek kötü bir uygulamadır.
andrew.fox

8

Sorunuzun tam kapsamını gerçekten anlamıyorum, ancak ihtiyacınız olan tek şey dizenin bir karmasıysa, bunu elde etmek çok kolaydır.

GetHashCode yöntemini kullanmanız yeterlidir.

Bunun gibi:

string hash = username.GetHashCode();

1
Evet, aradığı bu. Ama bu kod büyük bir hatadır. İnt hash = "kullanıcı adı" .GetHasCode () gibi yazmayı gösterin;
Edy Cu

3
Kullanıcı adını neden çift tırnak içine aldınız? Bu, 'kullanıcı adı' kelimesinin karmasını ve şimdi kullanıcı adı değişkeninde ne olduğunu alacak.
Cyril Gupta

15
GetHashCode'daki değerleri saklamayın, 32x ve 64x için farklı
Slava 9'13

13
Bu, parola karması oluşturmanın kötü bir yoludur. GetHashCode () ile, aynı numaranın farklı bir bilgisayardan üretileceğini varsayamazsınız. Sha1 hash yöntemini veya başka bir şeyi kullanın (daha sonra bir örnek
göndereceğim

2
Bunun GetHashCodekriptografik olarak güvenli bir karma algoritma olmadığı unutulmamalıdır . Güvenli bir algoritma için en azından SHA256 kullanın veya daha iyisi BCrypt veya Scrypt kullanın.
Muhammad Rehan Saeed

5

Sanırım aradığınız şey karma değil, şifreleme. Hashing ile, orijinal dosya adını "hash" değişkeninden alamazsınız. Şifreleme ile yapabilirsiniz ve güvenlidir.

NET'te şifreleme hakkında daha fazla bilgi için VB.NET ile ASP.NET'te AES konusuna bakın .


evet, bence şifreleme, ancak sadece sonuç karmasını karşılaştırmak istiyorum. Sayfayı yeniden yönlendirdikten sonra.
Edy Cu

Hashing uygulanmış dosya adını neyle karşılaştırmak istiyorsunuz?
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();
    }

3
SHA1'i bu bağlantıdan KULLANMAYIN , SHA1 eski ve güvenli olmayan bir algoritmadır. En azından SHA256'yı kullanın veya daha iyisi BCrypt veya Scrypt kullanın.
Muhammad Rehan Saeed

SCrypt kullanımıyla ilgili şu örneğe bakın: stackoverflow.com/questions/20042977/…
Muhammad Rehan Saeed

1

Performans önemli bir sorun değilse, şu yöntemlerden herhangi birini de kullanabilirsiniz:
(Karma dizesinin büyük harf olmasını istiyorsanız, değiştirin"x2" olan "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")));
}

veya:

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

Şimdiye kadarki en kısa ve en hızlı yol. Sadece 1 satır!

    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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.