Why is my C# hash different?
The algorithm is the same everywhere; the bytes going in are not. The usual reasons, in order:
- Encoding.Unicode instead of Encoding.UTF8.
Encoding.Unicodeis UTF-16: two bytes per character, so every hash is different from what online tools and other languages give for the same text. UseEncoding.UTF8. Switch "The text is" above to UTF-16 to see the difference. - A line break.
echo "text" | sha256sumhashes "text\n". Useecho -norprintf. Text read from a file may also end with a line break, or start with a UTF-8 byte order mark. - Upper or lower case hex.
Convert.ToHexStringwrites uppercase,Convert.ToHexStringLower(.NET 9 and later) lowercase, andBitConverter.ToStringadds dashes. Compare hashes as bytes, or both in the same case.
File checksums
To check a download, hash the file and compare with the published value: pick the file above, or run sha256sum file on Linux, shasum -a 256 file on macOS, or Get-FileHash file in PowerShell (SHA-256 by default, uppercase). In C#, SHA256.HashData(stream) reads the file without loading it into memory.
Not for passwords
SHA-256 is fast by design, which is what makes it wrong for passwords: an attacker can try billions of guesses. Store passwords with a slow, salted function: PBKDF2 (what ASP.NET Core Identity uses) or bcrypt.
FAQ
How long is a SHA-256 hash?
32 bytes: 64 hexadecimal characters or 44 Base64 characters. SHA-384 is 48 bytes and SHA-512 is 64 bytes.
Can a SHA-256 hash be reversed?
No. It is a one-way function. Short or common inputs can be found by guessing, which is why passwords need a salt and a slow function instead.
How do I compute SHA-256 in C#?
SHA256.HashData(Encoding.UTF8.GetBytes(text)) returns the 32 bytes; Convert.ToHexStringLower turns them into the usual hex string (.NET 9 and later; before that, Convert.ToHexString(hash).ToLowerInvariant()).
Why does my C# SHA-256 not match an online tool?
Almost always the input bytes: Encoding.Unicode (UTF-16) instead of Encoding.UTF8, a trailing line break, or a byte order mark. The hex case can also differ.