59

是否可以在不提供纯文本密码的情况下在 PostgreSQL 中创建用户(理想情况下,我希望能够创建一个仅提供使用 sha-256 加密的密码的用户)?

我想做的是用类似的东西创建一个用户:

CREATE USER "martin" WITH PASSWORD '$6$kH3l2bj8iT$KKrTAKDF4OoE7w.oy(...)BPwcTBN/V42hqE.';

有什么办法吗?

谢谢您的帮助。

4

4 回答 4

91

如文档( CREATE ROLEmd5 )中所述,您可以提供已经用 散列的密码:

ENCRYPTED UNENCRYPTED 这些关键字控制密码是否在系统目录中加密存储。(如果两者都没有指定,则默认行为由配置参数 password_encryption 确定。)如果提供的密码字符串已经是 MD5 加密格式,则无论是否指定 ENCRYPTED 或 UNENCRYPTED ,它都按原样加密存储(因为系统无法解密指定的加密密码字符串)。这允许在转储/恢复期间重新加载加密密码。

这里缺少的信息是 MD5 加密的字符串应该是与用户名连接的密码,加上md5开头。

因此,例如u0使用密码创建foobar,知道md5('foobaru0')ac4bbe016b808c3c0b816981f240dcae

CREATE USER u0 PASSWORD 'md5ac4bbe016b808c3c0b816981f240dcae';

然后 u0 将能够通过输入foobar密码登录。

我认为目前没有一种方法可以SHA-256代替md5PostgreSQL 密码。

于 2013-07-02T17:03:34.357 回答
8

我不知道有一种方法可以覆盖密码的默认 md5 加密,但是如果您有一个 ROLE(又名“用户”),它已经有一个 md5 加密的密码,那么您似乎可以提供它。使用 pg_dumpall -g 验证这一点(查看集群中的全局变量)例如。

psql postgres
create role foo with encrypted password foobar;
\q

-- View the role from pg_dumpall -g
pg_dumpall -g | grep foo
CREATE ROLE foo;
ALTER ROLE foo WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION PASSWORD 'md5c98cbfeb6a347a47eb8e96cfb4c4b890';

Or get it from:
select * from pg_catalog.pg_shadow;

-- create the role again with the already-encrypted password
psql postgres
drop role foo;
CREATE ROLE foo;
ALTER ROLE foo WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION PASSWORD 'md5c98cbfeb6a347a47eb8e96cfb4c4b890';
\q

-- view the ROLE with the same password
pg_dumpall -g | grep foo
CREATE ROLE foo;
ALTER ROLE foo WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN NOREPLICATION PASSWORD 'md5c98cbfeb6a347a47eb8e96cfb4c4b890';

创建角色的文档

于 2013-07-02T15:56:19.230 回答
5

更简单的方法是:

CREATE USER u0 PASSWORD 'foobar';

select * from pg_catalog.pg_shadow;

给出密码:md5ac4bbe016b808c3c0b816981f240dcae

于 2018-05-22T20:04:24.640 回答
2

至少从版本 10.10 开始,也可以使用 SCRAM-SHA-256。

CREATE USER user_name
WITH PASSWORD 'SCRAM-SHA-256$4096:UunGvPETiX/JNGBvjOgW9A==$CPGNh7/MRfs0ispH9/HSJajOI8Uhp+UCRo/b/ToXIEY=:L6NzxQ3XUeWEeRa+oiuajC9Vgl7wk6ZpHAHl+pv4m00=';
GRANT CONNECT ON DATABASE database_name TO user_name;

(重要的是不要忘记向新用户授予权限)

如果您希望默认使用 SCRAM,可以将 password_cryptography 设置为 SCRAM-SHA-256:

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

我知道可以设置密码也避免 SQL 语句,这个到文档的链接应该会有所帮助。也许,有点不那么冗长。

无论如何,应尽可能避免使用 md5,SCRAM 是一种更可靠的密码存储方式。

如果您找不到创建 Postgres 接受的 SCRAM 字符串的方法,您可以使用以下代码让它为您创建一个。

  1. 记得将 password_encryption 设置为 SCRAM

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

    这不能在事务块中运行。例如,如果您正在使用迁移文件,您可能必须仅使用这两个命令创建两个不同的文件。

  2. 使用您需要编码的密码创建一个用户。

    CREATE USER tmp_user_to_create_a_password
    WITH PASSWORD 'your_password';
    
  3. 使用 SCRAM 加密读取密码。

    SELECT rolpassword
    FROM pg_catalog.pg_authid
    WHERE rolname='tmp_user_to_create_a_password';
    
  4. 删除用户

    DROP USER IF EXISTS tmp_user_to_create_a_password;
    
  5. 现在您可以在不使用纯文本的情况下创建用户。

    CREATE USER user_name
    WITH PASSWORD 'SCRAM-SHA-256$4096:3Lctb6GmH15cSO4bjcDsXg==$BSuI1c10J+NZ/Wmx4hwP4TvpdKEO9rl2hekZ8/DVuyA=:j8G9NJ30Xbz3Za2mjXF/j6O3DJbWyqvX886haFe4aCs=';
    GRANT CONNECT ON DATABASE database_name TO user_name;
    

    您现在可以使用“用户名”和“您的密码”登录。

于 2021-10-07T11:17:22.153 回答