Commit 0557a5dc authored by Heikki Linnakangas's avatar Heikki Linnakangas

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
parent e6e9c4da
...@@ -26,10 +26,10 @@ ...@@ -26,10 +26,10 @@
* is in "raw" number of bytes, the actual nonces sent over the wire are * is in "raw" number of bytes, the actual nonces sent over the wire are
* encoded using only ASCII-printable characters. * encoded using only ASCII-printable characters.
*/ */
#define SCRAM_RAW_NONCE_LEN 10 #define SCRAM_RAW_NONCE_LEN 18
/* length of salt when generating new verifiers */ /* length of salt when generating new verifiers */
#define SCRAM_DEFAULT_SALT_LEN 10 #define SCRAM_DEFAULT_SALT_LEN 12
/* default number of iterations when generating verifier */ /* default number of iterations when generating verifier */
#define SCRAM_DEFAULT_ITERATIONS 4096 #define SCRAM_DEFAULT_ITERATIONS 4096
......
...@@ -27,7 +27,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL; ...@@ -27,7 +27,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL;
-- --
-- Since the salt is random, the exact value stored will be different on every test -- Since the salt is random, the exact value stored will be different on every test
-- run. Use a regular expression to mask the changing parts. -- run. Use a regular expression to mask the changing parts.
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 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
FROM pg_authid FROM pg_authid
WHERE rolname LIKE 'regress_passwd%' WHERE rolname LIKE 'regress_passwd%'
ORDER BY rolname, rolpassword; ORDER BY rolname, rolpassword;
...@@ -63,7 +63,7 @@ ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ ...@@ -63,7 +63,7 @@ ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ
SET password_encryption = 'scram-sha-256'; SET password_encryption = 'scram-sha-256';
ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
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 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
FROM pg_authid FROM pg_authid
WHERE rolname LIKE 'regress_passwd%' WHERE rolname LIKE 'regress_passwd%'
ORDER BY rolname, rolpassword; ORDER BY rolname, rolpassword;
......
...@@ -28,7 +28,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL; ...@@ -28,7 +28,7 @@ CREATE ROLE regress_passwd5 PASSWORD NULL;
-- --
-- Since the salt is random, the exact value stored will be different on every test -- Since the salt is random, the exact value stored will be different on every test
-- run. Use a regular expression to mask the changing parts. -- run. Use a regular expression to mask the changing parts.
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 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
FROM pg_authid FROM pg_authid
WHERE rolname LIKE 'regress_passwd%' WHERE rolname LIKE 'regress_passwd%'
ORDER BY rolname, rolpassword; ORDER BY rolname, rolpassword;
...@@ -54,7 +54,7 @@ SET password_encryption = 'scram-sha-256'; ...@@ -54,7 +54,7 @@ SET password_encryption = 'scram-sha-256';
ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
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 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
FROM pg_authid FROM pg_authid
WHERE rolname LIKE 'regress_passwd%' WHERE rolname LIKE 'regress_passwd%'
ORDER BY rolname, rolpassword; ORDER BY rolname, rolpassword;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment