Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

1.2K
Views
How to Generate SCRAM-SHA-256 to Create Postgres 13 User

I want to create a Postgres user with the CREATE USER command and an already hashed digest for the password. After much searching, I thought it was only possible with MD5 until I found this link. I've verified that works like so:

CREATE USER test_user WITH LOGIN PASSWORD 'SCRAM-SHA-256$4096:H45+UIZiJUcEXrB9SHlv5Q==$I0mc87UotsrnezRKv9Ijqn/zjWMGPVdy1zHPARAGfVs=:nSjwT9LGDmAsMo+GqbmC2X/9LMgowTQBjUQsl45gZzA=';

I can then log into that user with the password, which the article doesn't necessarily say but it's "postgres". Now that I know it's possible, how using .NET 5 can I generate a scram-sha-256 digest that Postgres 13 will accept? I've seen other Postgres articles using the outdated MD5 hash where the username is concatenated with the password before hashing. Does that need to happen with the new scram-sha-256 as well? I couldn't find much information on this topic anywhere.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

I don't know how to generate a scram-sha-256 digest with .NET 5. However, if the scram-sha-256 digest is all you need you can use a workaround by creating a dummy postgres user locally and echoing the encryped password with the createuser command.

For example (usually you run this as Linux postgres user: su postgres):

$ createuser dummyuser -e --pwprompt
Enter password for new role: 
Enter it again: 
SELECT pg_catalog.set_config('search_path', '', false);
CREATE ROLE dummyuser PASSWORD 'SCRAM-SHA-256$4096:VnimR0aOywxZzY82nzy9Fg==$qF9uMCU6YsKoecvRjP8jSmZZxrXgn5VwzhHwfoWo5Xg=:xGYfBUvGsu9mZFiq1nSFaHi7uN8n47IDwHO32IeK9io=' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;

You can now just copy the digest into your query. Of course that only works if you don't need to generate the digest dynamically with .NET.

Don't forget to drop the dummy user:

$ dropuser dummyuser

Also, in case your local postgres db still uses/generates md5 you have to change that to scram by using following query, ran as postgres superuser:

ALTER SYSTEM SET password_encryption = 'scram-sha-256';
SELECT pg_reload_conf();

If you, however, want to create the digest dynamically with .NET, I recommend you to have a look at the source code of the createuser command...

Update one day later:

Here is the specific source code of the createuser command that encrypts the password into a scram-sha-256 string:

  • https://github.com/postgres/postgres/blob/6beb38cfc9ddd4cd3d2eb5402981ebdd69a618b4/src/interfaces/libpq/fe-auth-scram.c#L884-L921

To make life easier, here are links to the functions (probably not all) the above function is calling

  • https://github.com/postgres/postgres/blob/6beb38cfc9ddd4cd3d2eb5402981ebdd69a618b4/src/common/saslprep.c#L1023-L1245
  • https://github.com/postgres/postgres/blob/6beb38cfc9ddd4cd3d2eb5402981ebdd69a618b4/src/common/scram-common.c#L160-L274

You should be able to rewrite that code in .NET or any other language. Hope it helps!

over 4 years ago · Santiago Trujillo Report

0

If your intent is to generate a SCRAM-SHA-256 password before you have an operational database, then I found out you can use this method to generate a password hash using Docker tooling.

docker run --rm -it --name postgres-dummy -d -e POSTGRES_HOST_AUTH_METHOD=trust postgres:14-alpine
docker exec -it postgres-dummy psql -U postgres
 \password
 (type in your password twice)
 select rolpassword from pg_authid where rolname = 'postgres';
 \q
docker stop postgres-dummy

I know it's not a way to do it in .NET, but hopefully it is useful for someone.

over 4 years ago · Santiago Trujillo Report

0

Someone built a Go tool to do this:

https://github.com/supercaracal/scram-sha-256

Here's a python 3 port based on that Go project:

from base64 import standard_b64encode
from hashlib import pbkdf2_hmac, sha256
from os import urandom
import hmac
import sys


salt_size = 16
digest_len = 32
iterations = 4096


def b64enc(b: bytes) -> str:
    return standard_b64encode(b).decode('utf8')


def pg_scram_sha256(passwd: str) -> str:
    salt = urandom(salt_size)
    digest_key = pbkdf2_hmac('sha256', passwd.encode('utf8'), salt, iterations,
                             digest_len)
    client_key = hmac.digest(digest_key, 'Client Key'.encode('utf8'), 'sha256')
    stored_key = sha256(client_key).digest()
    server_key = hmac.digest(digest_key, 'Server Key'.encode('utf8'), 'sha256')
    return (
        f'SCRAM-SHA-256${iterations}:{b64enc(salt)}'
        f'${b64enc(stored_key)}:{b64enc(server_key)}'
    )


def print_usage():
    print("Usage: provide single password argument to encrypt")
    sys.exit(1)


def main():
    args = sys.argv[1:]

    if args and len(args) > 1:
        print_usage()

    if args:
        passwd = args[0]
    else:
        passwd = sys.stdin.read().strip()

    if not passwd:
        print_usage()

    print(pg_scram_sha256(passwd))


if __name__ == "__main__":
    main()

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!