133

I have a problem when trying get a hash string in c#.

I already tried a few websites, but most of them are using files to get the hash. Others that are for strings are a bit too complex. I found examples for Windows authentication for web like this:

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

I need to use a hash to make a string that contains a filename more secure. How can I do that?

Example:

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

Should I use another hashing algorithm and not "md5"?

2
  • 3
    in 2022 use this Convert.ToBase64String(SHA256.HashData(Encoding.UTF8.GetBytes(mySecretString))) Commented Nov 11, 2022 at 15:51
  • Above doesn't work for me: "SHA256 does not contain a definition for HashData" Commented Feb 7 at 14:19

8 Answers 8

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

Additional Notes

  • Since MD5 and SHA1 are obsolete and insecure algorithms, this solution uses SHA256. Alternatively, you can use BCrypt or Scrypt as pointed out in comments.
  • Also, consider "salting" your hashes and use proven cryptographic algorithms, as pointed out in comments.
Sign up to request clarification or add additional context in comments.

11 Comments

DO NOT USE MD5 OR SHA1, they are obsolete and insecure algorithms. Use SHA256 at the very least or even better use BCrypt or Scrypt.
@Muh It can easily be used for checksums, because its much faster than SHA512. But indeed to store Passwords, it is not recommended, which is right.
What does this b.ToString("X2") mean ?
FYI It IS perfectly legitimate to use MD5 or SHA1 if your not using the hash as a cryptographic hash, for example as a hash of content for comparison. The advantage there of MD5 (for example) is speed of computation, that fact that they are insecure is then irrelevant.
|
78

The fastest way, to get a hash string for password store purposes, is a following code:

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

Remarks:

  • if the method is invoked often, the creation of sha variable should be refactored into a class field;
  • output is presented as encoded hex string;

10 Comments

SHA1Managed class is not very costly. it consumes about 130 bytes and initialize them to some static value, but that is all. so there shouldn't be a performance problem in most cases.
Also SHA1Managed is IDisposable and thus require to wrap its usage into a using block.
@MuhammadRehanSaeed when I said SHA1Managed is not costly, I mean its creation is not. Also, a hashing algorithm is not necessary costly. It only have to be (extremely) costly when you want to find a collision.
@King_Fisher - it's impossible! Hash is a one way function, information is lost. If you need to decrypt, you need to use encryption method not hashing. BTW, encrypting passwords is a bad practice.
@JohnHenckel do you want MS to put all possible usages into the library? It would weigh 1 GB. This method uses "composite" technique to build one of possible solutions. You can change Sha to MD5 or UTF to ASCII. However you like.
|
18

All the hashing code samples here are outdated. In.NET 5, a new way of hashing data is provided to us which is double fast and does zero memory allocation. ain't that cool? You just need to use the new static HashData(byte[]) on your favorite hashing algorithm class.

byte[] buffer = Encoding.UTF8.GetBytes(input);
byte[] digest = SHA256.HashData(buffer);

Microsoft has a new rule in its analyzer to detect legacy usages and replace them with the new API.

5 Comments

The whole point of secure hashing, such as for passwords, is that it needs to be slow to produce the hash. That's what provides defenses against brute forcing. If you use a hashing algorithm that's fast to compute then it's that much easier to break it.
@Servy your point is correct but totally unrelated to my post.
It's not unrelated at all. Suggesting a solution because it's super fast means suggesting a solution that's necessarily insecure, since it being slow is a key component of its security.
@Servy The computation time is dependent on the algorithm you choose. The legacy implementation of hashing algorithm is not performant in terms of CPU and memory. It means that under normal circumstances, they put more load on your servers unnecessarily. If you want to be secure, still you need select your algorithm wisely, but it doesn't mean you should select the poorly implemented legacy APIs.
@Servy is partially correct. For weak password hashing (say 1 to 6 chars), you want to use an slow processing algorithm such as bcrypt for optimal protection, as very little time difference in cracking a weak hashed password using SHA1 or SHA-256. But for long/strong passwords - ideally adding in a large salt component, then fast hash rate is optimal, as the full bounds of 2^256 combinations are in play.
12

I don't really understand the full scope of your question, but if all you need is a hash of the string, then it's very easy to get that.

Just use the GetHashCode method.

Like this:

string hash = username.GetHashCode();

8 Comments

Yes, that it what looking for. But it code is big mistake. Show write like int hash = "username".GetHasCode();
Why have you put username in double quotes? That will get the hash of the word 'username' and now what's in the username variable.
don't store values from GetHashCode, it is different for 32x and 64x
This is a bad way of creating a password hash. With GetHashCode() you can't assume that the same number will be generated of different computer. Use Sha1 hash method or something (I'll post an example later)
It should be noted that GetHashCode is not a cryptographically secure hashing algorithm. Use SHA256 at the very least or even better use BCrypt or Scrypt for a secure algorithm.
|
5

I think what you're looking for is not hashing but encryption. With hashing, you will not be able to retrieve the original filename from the "hash" variable. With encryption you can, and it is secure.

See AES in ASP.NET with VB.NET for more information about encryption in .NET.

2 Comments

yes, i think is encryption, but i just wish to compare result hash. After redirect page.
What do you want to compare the hashed filename with?
3

The shortest and fastest way ever. Only 1 line!

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

1 Comment

Another 1-Line version using StringBuilder & Linq public static string Hash(string value) => string.IsNullOrEmpty(value) ? value : SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(value)).Aggregate(new StringBuilder(), (sb, b) => sb.Append(b.ToString("X2"))).ToString();
1

If performance is not a major concern, you can also use any of these methods:
(In case you wanted the hash string to be in upper case, replace "x2" with "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")));
}

or:

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

Comments

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

2 Comments

DO NOT USE SHA1 from this link, SHA1 is an obsolete and insecure algorithms. Use SHA256 at the very least or even better use BCrypt or Scrypt.
See this example of using SCrypt: stackoverflow.com/questions/20042977/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.