Stringa hash in c #


91

Ho un problema quando provo a inserire una stringa hash c#.

Ho già provato alcuni siti Web, ma la maggior parte di essi utilizza file per ottenere l'hash. Altri che sono per gli archi sono un po 'troppo complessi. Ho trovato esempi per l'autenticazione di Windows per il web come questo:

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

Ho bisogno di usare un hash per rendere più sicura una stringa che contiene un nome di file. Come posso fare ciò?

Esempio:

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

Devo usare un altro algoritmo di hashing e non "md5"?

Risposte:


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

Note aggiuntive

  • Poiché MD5 e SHA1 sono algoritmi obsoleti e non sicuri , questa soluzione utilizza SHA256. In alternativa, puoi utilizzare BCrypt o Scrypt come indicato nei commenti.
  • Inoltre, considera il " salting " dei tuoi hash e utilizza algoritmi crittografici collaudati, come sottolineato nei commenti.

46
NON USARE MD5 O SHA1 , sono algoritmi obsoleti e insicuri. Usa almeno SHA256 o meglio ancora usa BCrypt o Scrypt.
Muhammad Rehan Saeed,

1
Vedere questo esempio di utilizzo scrypt: stackoverflow.com/questions/20042977/...
Muhammad Rehan Saeed

6
@ Muh Può essere facilmente utilizzato per i checksum, perché è molto più veloce di SHA512. Ma in effetti per memorizzare le password, non è raccomandato, il che è giusto.
LuckyLikey

5
Cosa significa questo b.ToString("X2")?
Bilal Fazlani


60

Il modo più veloce, per ottenere una stringa hash per scopi di archiviazione delle password, è un codice seguente:

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

Osservazioni:

  • se il metodo viene invocato spesso, la creazione della shavariabile dovrebbe essere rifattorizzata in un campo di classe;
  • l'output viene presentato come stringa esadecimale codificata;

SHA1Managedla classe non è molto costosa. consuma circa 130 byte e li inizializza su un valore statico, ma questo è tutto. quindi nella maggior parte dei casi non dovrebbero esserci problemi di prestazioni.
Earth Engine

1
Inoltre SHA1Managedè IDisposablee quindi richiede di avvolgere il suo utilizzo in un usingblocco.
Earth Engine

Lo scopo del Disposemetodo è cancellare il buffer interno. In caso contrario, rischi di attacchi di memoria.
Earth Engine

3
@MuhammadRehanSaeed quando ho detto che SHA1Managednon è costoso, voglio dire che la sua creazione non lo è. Inoltre, un algoritmo di hashing non è necessariamente costoso. Deve essere (estremamente) costoso solo quando vuoi trovare una collisione.
Earth Engine

1
@ King_Fisher - è impossibile! L'hash è una funzione unidirezionale, le informazioni vengono perse. Se è necessario decrittografare, è necessario utilizzare il metodo di crittografia non hashing. A proposito, crittografare le password è una cattiva pratica.
andrew.fox

8

Non capisco davvero l'ambito completo della tua domanda, ma se tutto ciò di cui hai bisogno è un hash della stringa, allora è molto facile ottenerlo.

Usa semplicemente il metodo GetHashCode.

Come questo:

string hash = username.GetHashCode();

1
Sì, è quello che stai cercando. Ma il codice è un grosso errore. Mostra write come int hash = "username" .GetHasCode ();
Edy Cu

3
Perché hai messo il nome utente tra virgolette? Questo otterrà l'hash della parola "nome utente" e ora cosa c'è nella variabile nome utente.
Cyril Gupta

14
non memorizzare i valori da GetHashCode, è diverso per 32x e 64x
Slava

12
Questo è un cattivo modo per creare un hash della password. Con GetHashCode () non puoi presumere che lo stesso numero verrà generato su computer diversi. Usa il metodo hash Sha1 o qualcosa del genere (posterò un esempio più tardi)
andrew.fox

2
Va notato che GetHashCodenon è un algoritmo di hashing crittograficamente sicuro. Usa SHA256 come minimo o meglio ancora usa BCrypt o Scrypt per un algoritmo sicuro.
Muhammad Rehan Saeed,

5

Penso che quello che stai cercando non sia l'hashing ma la crittografia. Con l'hashing, non sarai in grado di recuperare il nome del file originale dalla variabile "hash". Con la crittografia puoi farlo ed è sicuro.

Vedere AES in ASP.NET con VB.NET per ulteriori informazioni sulla crittografia in .NET.


sì, penso sia la crittografia, ma desidero solo confrontare l'hash dei risultati. Dopo la pagina di reindirizzamento.
Edy Cu

Con cosa vuoi confrontare il nome file con 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();
    }

3
NON USARE SHA1 da questo collegamento, SHA1 è un algoritmo obsoleto e insicuro. Usa almeno SHA256 o meglio ancora usa BCrypt o Scrypt.
Muhammad Rehan Saeed

Vedere questo esempio di utilizzo scrypt: stackoverflow.com/questions/20042977/...
Muhammad Rehan Saeed

1

Se le prestazioni non sono una delle principali preoccupazioni, puoi anche utilizzare uno di questi metodi:
(Nel caso in cui desideri che la stringa hash sia in lettere maiuscole, sostituisci "x2"con "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")));
}

o:

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

Il modo più breve e veloce di sempre. Solo 1 riga!

    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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.