Migrating your PostgreSQL password hashing from the legacy MD5 algorithm to SCRAM-SHA-256 is a critical security upgrade. This guide walks through the impact analysis and provides a step-by-step migration plan, including detection scripts, password reset strategies, and rollback considerations.

Why Migrate from MD5 to SCRAM-SHA-256?
MD5 password hashing has known vulnerabilities (fast hash, collision attacks). SCRAM-SHA-256 (Salted Challenge Response Authentication Mechanism with SHA-256) is the modern standard in PostgreSQL 10+. It uses a salted, iterated hash that is resistant to brute-force and rainbow-table attacks. Compliance frameworks (e.g., 等级保护) often require SCRAM-SHA-256.
Understanding the Impact
Key Concepts
password_encryption(inpostgresql.conf): Controls the algorithm used for new passwords set viaCREATE USERorALTER USER. Changing it does not re-hash existing passwords.pg_hba.confauthentication method:md5in PostgreSQL 10+ actually accepts both MD5 and SCRAM-SHA-256 hashes.scram-sha-256only accepts SCRAM-SHA-256.- Password storage: Hashes are stored in
pg_authid.rolpassword. MD5 hashes start withmd5, SCRAM-SHA-256 hashes start withSCRAM-SHA-256$.
Impact Matrix
| Change | Effect |
|---|---|
Change password_encryption to scram-sha-256 |
New passwords use SCRAM-SHA-256; existing MD5 passwords remain valid if pg_hba.conf uses md5 |
Change pg_hba.conf to scram-sha-256 |
Only SCRAM-SHA-256 hashes can authenticate; MD5 users will be locked out |
| No password reset | Users with MD5 hashes cannot log in after switching pg_hba.conf to scram-sha-256 |
Step-by-Step Migration Plan
Phase 1: Inventory and Preparation
- Identify all login roles with MD5 hashes:
SELECT rolname, rolpassword
FROM pg_authid
WHERE rolpassword LIKE 'md5%'
AND rolcanlogin = true;
Check client driver compatibility: Ensure all client libraries (psql, JDBC, Npgsql, etc.) support SCRAM-SHA-256. PostgreSQL 10+ clients are compatible.
Backup
pg_authid:
COPY pg_authid TO '/tmp/pg_authid_backup.csv' WITH CSV HEADER;
Phase 2: Password Migration (with pg_hba.conf still using md5)
- Set
password_encryptiontoscram-sha-256inpostgresql.conf:
password_encryption = scram-sha-256
- Reload configuration:
pg_ctl reload
# or SQL: SELECT pg_reload_conf();
- Reset passwords for all MD5 users. For system users with known passwords:
ALTER USER postgres PASSWORD 'admin_password';
ALTER USER replicator PASSWORD 'replication_password';
For application users, collect passwords from config files and reset:
# Python example
users = {
'app_user1': 'pwd_from_config',
'app_user2': 'pwd_from_config',
}
for user, pwd in users.items():
execute_sql(f"ALTER USER {user} PASSWORD '{pwd}';")
- Verify no MD5 hashes remain:
SELECT rolname, rolpassword FROM pg_authid
WHERE rolpassword LIKE 'md5%' AND rolcanlogin = true;
-- Should return no rows
Phase 3: Switch Authentication Method
Edit
pg_hba.conf: Changemd5toscram-sha-256for all relevant lines.Reload configuration:
pg_ctl reload
- Test login:
psql -U postgres -d postgres
Phase 4: Validation
- Verify all application connections work.
- For replication users, update
primary_conninfoif necessary. - Confirm no leftover MD5 hashes:
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%' AND rolcanlogin = true;
Common Pitfalls
- Forgetting replication users: Replication roles (e.g.,
replicator) also need password resets; otherwise replication breaks. - Skipping client compatibility: Older drivers (pre-PG10) may not support SCRAM-SHA-256. Upgrade them first.
- Assuming
password_encryptionretroactively changes existing hashes: It does not. You must explicitly reset passwords. - No rollback plan: MD5 hashes cannot be converted back to MD5 from SCRAM-SHA-256. Keep a backup of
pg_authid. - Using
scram-sha-256inpg_hba.confbefore all passwords are migrated: Users with MD5 hashes will be locked out immediately.
Rollback Strategy
If you need to revert:
- Restore
pg_authidfrom backup. - Set
password_encryption = md5andpg_hba.confback tomd5. - Reload configuration.
- Reset passwords again (since SCRAM-SHA-256 hashes are not backward-compatible).
FAQ
What happens if I change password_encryption but not pg_hba.conf?
New passwords will be hashed with SCRAM-SHA-256, but existing MD5 passwords remain usable because md5 in pg_hba.conf accepts both. This is a safe intermediate step.
Can I convert MD5 hashes to SCRAM-SHA-256 without knowing the plaintext password?
No. MD5 hashing is one-way. You must know the original password to re-hash it with SCRAM-SHA-256.
How do I handle application users whose passwords I don't know?
Options:
- Force password change on first login after migration.
- Temporarily keep
pg_hba.confasmd5for those users (not compliant). - Collect passwords from application configuration files before migration (recommended).
Does SCRAM-SHA-256 affect performance?
SCRAM-SHA-256 is more CPU-intensive than MD5 for authentication, but the overhead is negligible for typical login rates. The security benefits far outweigh the cost.
What about PostgreSQL versions before 10?
SCRAM-SHA-256 is supported from PostgreSQL 10. For older versions, upgrade PostgreSQL first.
Try it in our Bcrypt hash generator to understand modern hashing principles.