.NET hashing library

Hashing for C# with a simple, direct API.

Generate MD5 for compatibility, SHA-256 for integrity, HMAC-SHA-256 for authentication and modern password hashes in .NET applications.

netstandard2.0•MIT License•NuGet
quick-start.cs
using MD5Hash;

string checksum = "hello world".GetSHA256();

Console.WriteLine(checksum);
// b94d27b9934d3e08...
Choose the algorithm for the job

MD5 is not encryption and must not be used for passwords. Use MD5 only when you need to reproduce a legacy value or generate a compatible checksum. For new integrations, prefer SHA-256 or HMAC-SHA-256; for passwords, use PasswordHash.

Start in minutes

Installation

The MD5 package is available on NuGet and works with projects compatible with netstandard2.0. Install it in your project and import the MD5Hash namespace.

.NET CLI
dotnet add package MD5
Package Manager Console
Install-Package MD5

Then add using MD5Hash; to the file that uses the library.

Quick decision guide

Which method should I use?

The right algorithm depends on what you need to protect or compare:

Compatibility

MD5

Reproduce hashes from older systems or legacy checksums.

See GetMD5 →
Integrity

SHA-256

Compare files, payloads and content fingerprints.

See GetSHA256 →
Authentication

HMAC-SHA-256

Validate integrity with a shared secret key.

See GetHMACSHA256 →
Passwords

PasswordHash

Store and verify passwords without storing the original text.

See PasswordHash →

Content API

Generating content hashes

The extension methods accept the types used in everyday applications: string, byte[], serializable objects and Stream. The result is a lowercase hexadecimal string.

01

GetMD5

MD5 for compatibility and legacy checksums.

Use GetMD5 when a target system requires MD5 or when you need to preserve compatibility with existing values. For a non-extension helper, use Hash.Content.

String, bytes, object and stream
using System.IO;
using System.Text;
using MD5Hash;

string fromString = "123".GetMD5();
byte[] bytes = Encoding.UTF8.GetBytes("Hello, World!");
string fromBytes = bytes.GetMD5();
string fromObject = new { Id = 1, Name = "Test" }.GetMD5();
using var stream = File.OpenRead("archive.zip");
string fromStream = stream.GetMD5();

Strings use ASCII by default in GetMD5(string). For accents, emojis or other non-ASCII characters, specify EncodingType.UTF8:

string hash = "Hello, world! 👋".GetMD5(EncodingType.UTF8);
string helper = Hash.Content("123");
02

GetSHA256

SHA-256 for integrity and fingerprints.

For new checksums, SHA-256 is the recommended choice. The method produces 64 hexadecimal characters:

Content checksum
string checksum = "hello world".GetSHA256();
// b94d27b9934d3e08a52e52d7da7dabfa...

Strings and objects use UTF-8 by default. For large files, pass an open stream; the stream's current position is consumed while reading.

using FileStream file = File.OpenRead("report.pdf");
string checksum = file.GetSHA256();
03

GetHMACSHA256

Integrity with secret-key authentication.

HMAC-SHA-256 combines content with a secret key. It is useful when the recipient needs to verify that a message came from a party that knows the key. Never expose the key in source control.

Message and key
string secretKey = "a-secret-key";
string signature = "hello world".GetHMACSHA256(secretKey);

For bytes, pass both content and key as byte[]. For objects, the library serializes the object to JSON before calculating the HMAC.

byte[] payload = Encoding.UTF8.GetBytes("Hello, World!");
byte[] key = Encoding.UTF8.GetBytes("a-secret-key");
string signature = payload.GetHMACSHA256(key);
04

GetMD5WithSalt

Salted MD5 for historical compatibility.

This method exists to reproduce the library's legacy behavior. A salt changes the result, but does not make MD5 suitable for passwords. For new passwords, use PasswordHash.

string hash = "hello world".GetMD5WithSalt("randomSalt");
string objectHash = new { Id = 1 }.GetMD5WithSalt("randomSalt");
Compatibility detail: strings and objects calculate salt + content; byte arrays and streams calculate content + salt. This difference is intentional to preserve existing hashes.
byte[] data = Encoding.UTF8.GetBytes("Hello, World!");
byte[] salt = Encoding.UTF8.GetBytes("randomSalt");
string hash = data.GetMD5WithSalt(salt);

Credential storage

Password hashing with PasswordHash

Passwords should not be encrypted for later recovery. Generate a slow password hash, store the returned value and use the matching Verify... method at login. Each method creates a random salt and returns a self-contained string with the parameters needed for verification.

Recommendation

Start with HashArgon2 for new systems when the environment supports Argon2id. Use PBKDF2 for broad compatibility and bcrypt when you need to interoperate with existing bcrypt hashes.

Argon2id

PBKDF2-HMAC-SHA256

A broadly compatible option. The library default uses 600,000 iterations, a 16-byte salt and a 32-byte hash.

Generate and verify
string storedHash = PasswordHash.HashPBKDF2("my password");
bool valid = PasswordHash.VerifyPBKDF2("my password", storedHash);

bcrypt

Useful when your application needs the bcrypt format. The default work factor is 12 and is embedded in the resulting hash.

string storedHash = PasswordHash.HashBCrypt("my password");
bool valid = PasswordHash.VerifyBCrypt("my password", storedHash);

Argon2id

Recommended for new password storage. The default uses 3 iterations, 65,536 KiB of memory, parallelism 2, a 16-byte salt and a 32-byte hash.

string storedHash = PasswordHash.HashArgon2("my password");
bool valid = PasswordHash.VerifyArgon2("my password", storedHash);

// Named parameters can be supplied when tuning.
string tunedHash = PasswordHash.HashArgon2("my password", iterations: 3, memorySize: 65536, degreeOfParallelism: 2);
Best practice: store the complete string returned by the library and never compare password hashes manually. Tune parameters using measurements on production hardware.

Text and bytes

Choosing EncodingType

A hash is calculated over bytes. The same text can produce different results with different encodings. Use the enum when reproducing another system's format.

Values available in EncodingType
Value.NET encodingWhen to consider it
UTF8UTF-8Recommended choice for new text.
ASCIIASCIICompatibility with strictly ASCII content.
UTF7UTF-7Legacy integrations only.
UTF32UTF-32When the target requires this format.
UnicodeUTF-16 little-endianCompatibility with UTF-16 applications.
BigEndianUnicodeUTF-16 big-endianCompatibility with specific protocols.
DefaultEnvironment default encodingAvoid for values that must be reproducible across machines.

SHA-256 and HMAC-SHA-256 use UTF-8 by default for strings and objects. Legacy MD5 keeps ASCII for its string overload and UTF-8 for its object overload.

Quick reference

API reference

Public methods available
MethodInputsRecommended use
Hash.Contentstring, optional encodingStatic helper for MD5.
GetMD5string, object, byte[], StreamLegacy compatibility and checksums.
GetSHA256string, object, byte[], StreamContent integrity.
GetHMACSHA256Content + keyIntegrity and authentication.
GetMD5WithSaltContent + saltSalted legacy MD5 compatibility.
PasswordHash.HashPBKDF2 / VerifyPBKDF2Password + stored hashBroadly compatible password storage.
PasswordHash.HashBCrypt / VerifyBCryptPassword + stored hashbcrypt interoperability.
PasswordHash.HashArgon2 / VerifyArgon2Password + stored hashNew systems with Argon2id.

Common questions

Frequently asked questions

Is MD5 safe for passwords?

No. MD5 is too fast and was not designed to protect passwords. Use PasswordHash with Argon2id, PBKDF2 or bcrypt.

Does SHA-256 replace HMAC-SHA-256?

Not exactly. SHA-256 creates a public checksum. HMAC-SHA-256 uses a secret key and also lets you verify message authenticity.

Can I store the password hash directly in my database?

Yes. Store the complete string returned by HashPBKDF2, HashBCrypt or HashArgon2. It already contains the algorithm and parameters needed by the matching Verify... method.

What happens when I provide the wrong password?

The Verify... methods return false. A null password throws ArgumentNullException, so validate application input according to your business rules.

Ready to use it?

Install the package and generate your first hash.

Browse the source code, open an issue or install the latest version from NuGet.