From 0557a5dc2cf845639d384801b6861ebbd35dc7ee Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 5 May 2017 10:02:13 +0300 Subject: [PATCH] Make SCRAM salts and nonces longer. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- src/include/common/scram-common.h | 4 ++-- src/test/regress/expected/password.out | 4 ++-- src/test/regress/sql/password.sql | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.h index 307f92b54a..b5d107494c 100644 --- a/src/include/common/scram-common.h +++ b/src/include/common/scram-common.h @@ -26,10 +26,10 @@ * is in "raw" number of bytes, the actual nonces sent over the wire are * 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 */ -#define SCRAM_DEFAULT_SALT_LEN 10 +#define SCRAM_DEFAULT_SALT_LEN 12 /* default number of iterations when generating verifier */ #define SCRAM_DEFAULT_ITERATIONS 4096 diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.out index 9ec5a52bba..5b0b955b29 100644 --- a/src/test/regress/expected/password.out +++ b/src/test/regress/expected/password.out @@ -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 -- 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:$:') 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:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword; @@ -63,7 +63,7 @@ ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ SET password_encryption = 'scram-sha-256'; ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier 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:$:') 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:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword; diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sql index 1e022dbf2d..d2e9eea79d 100644 --- a/src/test/regress/sql/password.sql +++ b/src/test/regress/sql/password.sql @@ -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 -- 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:$:') 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:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword; @@ -54,7 +54,7 @@ SET password_encryption = 'scram-sha-256'; ALTER ROLE regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier 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:$:') 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:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' ORDER BY rolname, rolpassword; -- 2.40.0