Obtain SHA-256 string of a string
Asked Answered
D

5

72

I have some string and I want to hash it with the SHA-256 hash function using C#. I want something like this:

 string hashString = sha256_hash("samplestring");

Is there something built into the framework to do this?

Delude answered 8/6, 2013 at 12:5 Comment(4)
msdn.microsoft.com/en-us/library/… . -1.Mildred
Hashes work on bytes, not strings. So you first need to choose an encoding that transforms the string into bytes. I recommend UTF-8 for this.Clubman
Something tells me that people reading this post should also check: #4948822Fuzee
I'm curious why this question remains closed. It's a reasonable question with good working answers. Voting to re-open.Forebode
Q
177

The implementation could be like that

public static String sha256_hash(String value) {
  StringBuilder Sb = new StringBuilder();

  using (SHA256 hash = SHA256Managed.Create()) {
    Encoding enc = Encoding.UTF8;
    Byte[] result = hash.ComputeHash(enc.GetBytes(value));

    foreach (Byte b in result)
      Sb.Append(b.ToString("x2"));
  }

  return Sb.ToString();
}

Edit: Linq implementation is more concise, but, probably, less readable:

public static String sha256_hash(String value) {
  using (SHA256 hash = SHA256Managed.Create()) {
    return String.Concat(hash
      .ComputeHash(Encoding.UTF8.GetBytes(value))
      .Select(item => item.ToString("x2")));
  }
} 

Edit 2: .NET Core , .NET5, .NET6 ...

public static String sha256_hash(string value)
{
    StringBuilder Sb = new StringBuilder();

    using (var hash = SHA256.Create())            
    {
        Encoding enc = Encoding.UTF8;
        byte[] result = hash.ComputeHash(enc.GetBytes(value));

        foreach (byte b in result)
            Sb.Append(b.ToString("x2"));
    }

    return Sb.ToString();
}
Quail answered 8/6, 2013 at 15:57 Comment(6)
how would you decrypt the hash back into the password?Jerk
@daniel metlitski: you can't: hash is one way function, you can compute hash but can't obtain the argument back. When registering a new user, store not password but its hash; on authentication, compute hash on the password provided and compare the hash with the stored hash.Quail
@JuliusHolmberg: you have to 1. Allocate resources (using), 2. Deal with bytes: Encoding as well as GetBytes 3. Represent the outcome as a string - StringBuilder and ToString("x2")Quail
string.Join maybe?Tirado
string.Concat is shorter and more readable: just concat without any delimiterQuail
I would NOT recommend to store passwords using a simple hash. Actually just use a library that has the logic to store passwords (like identity). Even though you can't "decrypt" back you can use a dictionary attack with millions of common passwords whose hash are known. In order to avoid this you need to use hash + salt. You also need to store the salt securely. And there is probably more than I'm missing security-wise. Please use a library instead of trying to store passwords yourself.Matriarchy
H
23

From .NET 5 onwards, you can use the new Convert.ToHexString method to convert the hash byte array into a (hex) string without having to use a StringBuilder or .ToString("X0"), etc.:

public static string HashWithSHA256(string value)
{
  using var hash = SHA256.Create();
  var byteArray = hash.ComputeHash(Encoding.UTF8.GetBytes(value));
  return Convert.ToHexString(byteArray);
}
Hearts answered 13/9, 2021 at 20:32 Comment(2)
This almost works, but it returns a hash string with uppercase letters.Stav
Just add .ToLower() to the end of the return statement; which @samuel added but the editor removed!!Flowerlike
M
8

Simply:

string sha256(string s) => Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(s)));

Marjana answered 19/4, 2023 at 4:23 Comment(0)
I
1

I was looking for an in-line solution, and was able to compile the below from Dmitry's answer:

public static String sha256_hash(string value)
{
    return (System.Security.Cryptography.SHA256.Create()
            .ComputeHash(Encoding.UTF8.GetBytes(value))
            .Select(item => item.ToString("x2")));
}
Icelandic answered 29/5, 2018 at 18:58 Comment(3)
This implementation seems wrong to me. That select Returns IEnumerable<string>. And you copy-pasted a terrible naming convention.Fluoridation
This is actually the best answer just missing one function call. Here is what worked for me: return String.Concat((System.Security.Cryptography.SHA256.Create() .ComputeHash(Encoding.UTF8.GetBytes(value)) .Select(item => item.ToString("x2"))));Putrescent
I like it because it's single line and doesn't need a function by itself.Putrescent
S
1

I tried all of the above methods and none worked for me. This one is one I made that works flawlessly:

public static string Encrypt(string input)
{
    using (SHA256 sha256 = SHA256.Create())
    {
        // Convert the input string to a byte array
        byte[] inputBytes = Encoding.UTF8.GetBytes(input);

        // Compute the hash value of the input bytes
        byte[] hashBytes = sha256.ComputeHash(inputBytes);

        // Convert the hash bytes to a hexadecimal string
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hashBytes.Length; i++)
        {
            sb.Append(hashBytes[i].ToString("x2"));
        }

        return sb.ToString();
    }
}

Make sure to be using System.Security.Cryptography at the beginning of your code

using System.Security.Cryptography
Shulins answered 9/4, 2023 at 19:30 Comment(1)
Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, can you edit your answer to include an explanation of what you're doing and why you believe it is the best approach?Intuitive

© 2022 - 2024 — McMap. All rights reserved.