Skip to content

Commit 0557a5d

Browse files
committed
Make SCRAM salts and nonces longer.
The salt is stored base64-encoded. With the old 10 bytes raw length, it was always padded to 16 bytes after encoding. We might as well use 12 raw bytes for the salt, and it's still encoded into 16 bytes. Similarly for the random nonces, use a raw length that's divisible by 3, so that there's no padding after base64 encoding. Make the nonces longer while we're at it. 10 bytes was probably enough to prevent replay attacks, but there's no reason to be skimpy here. Per suggestion from Álvaro Hernández Tortosa. Discussion: https://www.postgresql.org/message-id/df8c6e27-4d8e-5281-96e5-131a4e638fc8@8kdata.com
1 parent e6e9c4d commit 0557a5d

File tree

3 files changed

+6
-6
lines changed

3 files changed

+6
-6
lines changed

src/include/common/scram-common.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@
2626
* is in "raw" number of bytes, the actual nonces sent over the wire are
2727
* encoded using only ASCII-printable characters.
2828
*/
29-
#define SCRAM_RAW_NONCE_LEN 10
29+
#define SCRAM_RAW_NONCE_LEN 18
3030

3131
/* length of salt when generating new verifiers */
32-
#define SCRAM_DEFAULT_SALT_LEN 10
32+
#define SCRAM_DEFAULT_SALT_LEN 12
3333

3434
/* default number of iterations when generating verifier */
3535
#define SCRAM_DEFAULT_ITERATIONS 4096

src/test/regress/expected/password.out

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL;
2727
--
2828
-- Since the salt is random, the exact value stored will be different on every test
2929
-- run. Use a regular expression to mask the changing parts.
30-
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/]+==)\$([a-zA-Z0-9+/]+=):([a-zA-Z0-9+/]+=)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
30+
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
3131
FROM pg_authid
3232
WHERE rolname LIKE 'regress_passwd%'
3333
ORDER BY rolname, rolpassword;
@@ -63,7 +63,7 @@ ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ
6363
SET password_encryption = 'scram-sha-256';
6464
ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
6565
CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
66-
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/]+==)\$([a-zA-Z0-9+/]+=):([a-zA-Z0-9+/]+=)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
66+
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
6767
FROM pg_authid
6868
WHERE rolname LIKE 'regress_passwd%'
6969
ORDER BY rolname, rolpassword;

src/test/regress/sql/password.sql

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL;
2828
--
2929
-- Since the salt is random, the exact value stored will be different on every test
3030
-- run. Use a regular expression to mask the changing parts.
31-
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/]+==)\$([a-zA-Z0-9+/]+=):([a-zA-Z0-9+/]+=)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
31+
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
3232
FROM pg_authid
3333
WHERE rolname LIKE 'regress_passwd%'
3434
ORDER BY rolname, rolpassword;
@@ -54,7 +54,7 @@ SET password_encryption = 'scram-sha-256';
5454
ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
5555
CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
5656

57-
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/]+==)\$([a-zA-Z0-9+/]+=):([a-zA-Z0-9+/]+=)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
57+
SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
5858
FROM pg_authid
5959
WHERE rolname LIKE 'regress_passwd%'
6060
ORDER BY rolname, rolpassword;

0 commit comments

Comments
 (0)