73

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?

4
  • 2
    msdn.microsoft.com/en-us/library/… . -1. Commented Jun 8, 2013 at 12:06
  • 3
    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. Commented Jun 9, 2013 at 11:04
  • Something tells me that people reading this post should also check: stackoverflow.com/questions/4948322/… Commented Aug 18, 2017 at 21:29
  • 2
    I'm curious why this question remains closed. It's a reasonable question with good working answers. Voting to re-open. Commented Apr 20, 2018 at 9:12

5 Answers 5

180

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(); } 
Sign up to request clarification or add additional context in comments.

6 Comments

how would you decrypt the hash back into the password?
@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.
@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")
string.Join maybe?
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.
|
24

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

2 Comments

This almost works, but it returns a hash string with uppercase letters.
Just add .ToLower() to the end of the return statement; which @samuel added but the editor removed!!
10

Simply:

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

Comments

2

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 

1 Comment

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

3 Comments

This implementation seems wrong to me. That select Returns IEnumerable<string>. And you copy-pasted a terrible naming convention.
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"))));
I like it because it's single line and doesn't need a function by itself.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.