Documentation
¶
Overview ¶
Package pgscram implements the PostgreSQL SCRAM-SHA-256 stored verifier (RFC 5802 / RFC 7677 + PostgreSQL's pg_authid encoding, hashcat mode 28600): the value stored in pg_authid.rolpassword for a role using scram-sha-256 authentication, the default since PostgreSQL 10 (2017) and the successor to the older md5 verifier (see internal/pgpassword). It is an offline credential primitive — compute the verifier for a candidate password, or verify a candidate against a verifier captured from a pg_authid / pg_dumpall --globals dump. Pure offline compute from operator-supplied strings; no network or device.
Stored verifier format ¶
PostgreSQL stores (pg_be_scram_build_secret):
SCRAM-SHA-256$<iterations>:<base64 salt>$<base64 StoredKey>:<base64 ServerKey>
derived from the password per RFC 5802:
SaltedPassword = PBKDF2-HMAC-SHA256(password, salt, iterations, dkLen=32) ClientKey = HMAC-SHA256(SaltedPassword, "Client Key") StoredKey = SHA256(ClientKey) ServerKey = HMAC-SHA256(SaltedPassword, "Server Key")
Verification recomputes StoredKey from the candidate password + the stored salt/iterations and constant-time compares it (knowledge of the password reproduces the StoredKey). The password is first prepared with SASLprep (RFC 4013); this package applies SASLprep's no-op fast path for the common ASCII case and otherwise uses the raw UTF-8 bytes — see the note below.
Wrap-vs-native judgement ¶
Native. The verifier is PBKDF2-HMAC-SHA256 (the generic in-tree internal/wpa.PBKDF2, the same primitive pbkdf2_password and wpa_pmk_derive use) plus two HMAC-SHA256 passes, one SHA-256, and base64 — all standard library. There is nothing to wrap; the only third-party option would be a PostgreSQL client/driver, unwarranted for a pure key-derivation. Consistent with internal/pgpassword, internal/mysqlpw, and internal/ldappw owning their crypto in-tree.
Verifiable / no confidently-wrong output ¶
Strongest verification class. The SaltedPassword / ClientKey / StoredKey / ServerKey chain is anchored byte-for-byte to the RFC 7677 §3 worked example (password "pencil", salt W22ZaJ0SNY7soEsUEjb6gQ==, i=4096): the package's derivation reproduces the RFC's ClientProof (p=) and ServerSignature (v=) exactly, and hence the StoredKey/ServerKey the verifier string carries. A malformed verifier (wrong prefix / field count / base64 / iteration count) is rejected with an error, never silently "verified".
Deferred: full SASLprep (RFC 4013) normalization of non-ASCII passwords — PostgreSQL applies SASLprep, but it is a no-op for ASCII passwords (the overwhelming majority) and falls back to the raw bytes on any SASLprep error; this package matches that behaviour for ASCII and uses raw UTF-8 otherwise, flagging that a non-ASCII password may need normalization. The older md5 verifier is handled by internal/pgpassword.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.