Overview
Introduction
PostgreSQL's older md5 password format has a detail that trips people up: it's not just md5(password), the username gets folded in too, specifically to stop identical passwords from producing identical hashes across different accounts.
This tool computes that exact format, 'md5' + md5(password + username), from a username and password you provide, entirely in your browser.
What Is Postgres Hash Calculator?
PostgreSQL's md5 password format, produced by \password on installations with password_encryption = md5, stores 'md5' concatenated with the hex MD5 digest of the password immediately followed by the username, with no separator.
It predates PostgreSQL 10's switch to SCRAM-SHA-256 as the default, and is what you'd still see in pg_shadow or pg_authid on an older or unmigrated configuration.
How Postgres Hash Calculator Works
Your password and username are concatenated in that exact order, password first, then username, with nothing between them, and encoded as UTF-8 bytes.
That combined byte string is hashed with MD5, hex-encoded, and prefixed with the literal string 'md5' to produce PostgreSQL's exact stored format.
When To Use Postgres Hash Calculator
Use this when working with an older PostgreSQL system that still uses password_encryption = md5, reproducing a pg_shadow/pg_authid value, or debugging authentication on a pre-10 or unmigrated installation.
Don't rely on this format for anything new; PostgreSQL itself has moved to SCRAM-SHA-256 by default specifically because md5's lack of iteration and weak hash choice make it far easier to attack than a modern scheme.
Often used alongside MongoDB Hash Calculator, MySQL Hash Calculator and Random Postgres Hash Generator.
Features
Advantages
- Exactly matches PostgreSQL's documented legacy md5 password format.
- The username-as-salt design, while weaker than a proper random salt, at least prevents trivial cross-user hash matching for shared passwords.
- Simple, deterministic, and easy to verify against a known pg_shadow/pg_authid value.
Limitations
- The username is a poor substitute for a real random salt: it's public knowledge and often guessable, so it doesn't meaningfully protect against a targeted attack on a known account.
- MD5 itself is fast and offers no configurable work factor, unlike bcrypt or SCRAM's PBKDF2-based iteration.
- Superseded by SCRAM-SHA-256 as PostgreSQL's default since version 10 (2017); this format is now specifically a legacy/compatibility concern.
Examples
Best Practices & Notes
Best Practices
- Always confirm concatenation order (password then username) when reproducing this format by hand; reversing it is the most common source of a mismatched hash.
- If you administer a PostgreSQL system still using password_encryption = md5, plan a migration to scram-sha-256.
- Never treat the username as a substitute for genuine password-hashing security; it only prevents identical hashes across different known usernames, nothing more.
Developer Notes
Implemented as 'md5' + toHex(md5(UTF8(password + username))) via @noble/hashes, matching PostgreSQL's documented format exactly, concatenation order is password first, then username, with no separator. Verified against a Postgres md5-format test vector (password 'secret123', username 'alice').
Postgres Hash Calculator Use Cases
- Reproducing a pg_shadow or pg_authid md5-format password hash by hand
- Debugging authentication on an older PostgreSQL installation still using password_encryption = md5
- Understanding PostgreSQL's pre-SCRAM password storage design during a migration
- Teaching why using a username as a salt-equivalent is weaker than genuine random salting
Common Mistakes
- Concatenating username before password instead of password before username, the single most common way to reproduce a mismatched hash.
- Assuming this format reflects current PostgreSQL defaults; version 10+ defaults to SCRAM-SHA-256 instead.
- Treating the username-based construction as equivalent in strength to a real random salt.
Tips
- If your target system is on PostgreSQL 10 or later with default settings, it's likely using SCRAM-SHA-256, not this md5 format, confirm password_encryption before assuming a match.
- This category's MongoDB Hash Calculator uses a structurally similar username-plus-password-hashing pattern (MONGODB-CR) if you want to compare the two legacy database credential formats.