PG口令加密算法中的scram-sha-256
Tags: md5PGscram-sha-256加密算法口令文件
口令认证
有几种基于口令的认证方法。
这些方法的过程类似,但是区别在于用户口令如何被存放在服务器上以及客户端提供的口令如何被通过连接发送。
scram-sha-256
方法scram-sha-256按照RFC 7677中的描述执行SCRAM-SHA-256认证。
它使用的是一种挑战-响应的方案,可以防止在不可信连接上对口令的嗅探并且支持在服务器上以一种加密哈希的方式存放口令,因此被认为是安全的。
这是当前提供的方法中最安全的一种,但是旧的客户端库不支持这种方法。
PostgreSQL10版本开始提供了基于SCRAM-SHA-256密码认证方法。在以前的版本中使用MD5认证方法,使用自定义安全性较低的challenge-response机制。 它可以防止密码嗅探,并避免以纯文本形式将密码存储在服务器上, 但如果攻击者设法从服务器窃取密码的哈希值,则无法再提供保护。此外,MD5哈希算法现在不再被认为对于确定的攻击是安全的。如RRFC 7677中所述, 方法scram-sha-256执行SCRAM-SHA-256认证。可防止密码在不可信连接上嗅探,并支持以密码散列的形式将密码存储在服务器上, 这种形式被认为是安全的。对于新上的实例建议直接使用SCRAM-SHA-256密码认证方法(initdb时指定auth为scram-sha-256),但是对于从MD5升级上来的实例稍微麻烦一点。
md5
方法md5使用一种自定义的安全性较低的挑战-响应机制。
它能防止口令嗅探并且防止口令在服务器上以明文存储,但是无法保护攻击者想办法从服务器上窃取了口令哈希的情况。
此外,现在认为MD5哈希算法对于确定攻击已经不再安全。
md5方法不能与db_user_namespace特性一起使用。
为了简化从md5方法到较新的SCRAM方法的转变,如果在pg_hba.conf中指定了md5但是用户在服务器上的口令是为SCRAM(见下文)加密的,则将自动选择基于SCRAM的认证。
password
方法password以明文形式发送口令,因此它对于口令“嗅探”攻击很脆弱。
如果可能应该尽量避免使用它。
不过,如果连接被SSL加密保护着,那么可以安全地使用password(不过如果依靠SSL,SSL证书认证可能是更好的选择)。
PostgreSQL数据库口令独立于操作系统用户口令。
每个数据库用户的口令被存储在pg_authid系统表中。
口令可以用 SQL 命令[CREATE USER](mk:@MSITStore:C:\Users\markbo\Desktop\PG培训认证学习资源(学员可分享)\PostgreSQL 11.2 中文手册.chm::/sql-createuser.html)和[ALTER ROLE](mk:@MSITStore:C:\Users\markbo\Desktop\PG培训认证学习资源(学员可分享)\PostgreSQL 11.2 中文手册.chm::/sql-alterrole.html)管理,例如CREATE ROLE foo WITH LOGIN PASSWORD 'secret'或者psql的\password命令。
如果没有为一个用户设置口令,那么存储的口令为空并且对该用户的口令认证总会失败。
不同的基于口令的认证方法的可用性取决于用户的口令在服务器上是如何被加密(或者更准确地说是哈希)的。由设置口令时的配置参数password_encryption控制。
如果口令使用scram-sha-256设置加密,那么它可以被用于认证方法scram-sha-256和password(但后一种情况中口令将以明文传输)。如上所述,在这种情况下,指定的认证方法md5将自动切换到使用scram-sha-256方法。
如果口令使用md5设置加密,那么它仅能用于md5和password认证方法说明(同样,后一种情况中口令以明文传输)。(之前的PostgreSQL发行版支持在服务器上存储明文口令。现在已经不可能了)。
要检查当前存储的口令哈希,可以参考系统表pg_authid。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | postgres=# select rolname,rolpassword from pg_authid ; rolname | rolpassword ---------------------------+--------------------------------------------------------------------------------------------------------------------------------------- pg_monitor | pg_read_all_settings | pg_read_all_stats | pg_stat_scan_tables | pg_read_server_files | pg_write_server_files | pg_execute_server_program | pg_signal_backend | appuser | md53db339d42b581e6c3ffd248be5660325 readonlyuser | md59f9b164f064a95803e4f0f0d0251ea7f appuser1 | SCRAM-SHA-256$4096:1M1EFYGaIL8DkeVUVbxOLg==$jJEROsIN+X9uLyGyrvjgC67jt//pRhkw2zuIM5RAiDo=:94voAJyZZ10ERtxzn5jiCTd4Weipq2f5Cpl/LZ0ztGk= appuser2 | SCRAM-SHA-256$4096:RYEVh9vftSKcdIjLVxMkBQ==$znbFCREYE7jEfoNGUb9rsxt+34cBaDVLspWFFF64A0g=:7lQSv+ZWxdL9ZbgcQKIREJvcgZ9QFiV15uud6Jgb1Jk= appauditor | SCRAM-SHA-256$4096:HmHOsSbZJtNARbtWrD/1xA==$EsIV4U/pdJ0dmESohyZFdyXPfXcaPcX3EZ2Ki1MI9Uo=:uu21WgIt9w8Hi4SzpRH4OHQoLhZ/HtPY8XiDIFM0/tU= user01 | user02 | u8 | SCRAM-SHA-256$4096:dfGNW8NQ6T/F4guhV2dltg==$DCwHU8lLDR4OwjKrBqk8w+mNxmA0SF4C5CrE2LGaxOA=:iFf/zQoNj2YziMukmRV3Bs2EBBbCxB/cTq6ksYwpf7k= postgres | SCRAM-SHA-256$4096:/nwCYIUEqkrn8TUEM8tj/g==$O+0V+mEnvbQaFObPPHUt5pLQaxyCsHfiDIfkIRuDjPs=:6ZhOBcsn4s6mWPLxB5Jh6sIk9temznEEiYcauC29c94= (17 rows) |
rolpassword中以md5开头的就是md5格式的密码,以SCRAM-SHA-256开头的就是SCRAM-SHA-256格式的密码。
配置用户密码认证及加密算法scram-sha-256
手册20.5中相关描述:要把现有的安装从md5升级到scram-sha-256,可以在确保所有在用的客户端已经足以支持SCRAM之后,在postgresql.conf中设置password_encryption = 'scram-sha-256',然后让所有用户设置新口令并且在pg_hba.conf中将认证方法说明改为scram-sha-256。
从MD5升级到SCRAM认证的方法见下:
步骤0:确定你是否需要能升级到SCRAM有关键的两个标准去确定能否从md5升级到SCRAM
你正在运行PostgreSQL 10及其更高版本
你用来连接到PostgreSQL数据库的驱动有SCRAM兼容性。PostgreSQL社区已经提供了一个驱动清单(https://wiki.postgresql.org/wiki/List_of_drivers#Drivers)
如果你的系统满足上述两个标准,你可以开始处理升级到SCRAM的过程。
步骤1: 验证你的pg_hba.conf设置
pg_hba.conf文件决定了你的客户端怎么连接到PostgreSQL Cluster中。如果你已经看过pg_hba.conf文件,你可能注意到与下面类似的行:
# TYPE DATABASE USER ADDRESS METHOD
local all all md5
上面的行表示任何尝试通过local connection连接到PostgreSQL Cluster中的user必须使用md5认证方法,
基于升级到SCRAM的目的,请确保你的password-based authentication 方法已经设置为md5,我们将在所有密码升级后更改此设置
步骤2:改变PostgreSQL的password_encryption参数
在Postgresql.conf参数文件中,有一个password_encryption参数,该参数决定了密码怎么被hash。此时,该参数默认设置为md5。
为了开始升级过程,你需要将password_encryption参数值改为scram-sha-256,如下所示:
1 | password_encryption = scram-sha-256 |
当上述修改完成后,请reload以便修改生效(不需要restart)
步骤3:决定哪些user需要升级
下一步是确定哪些user需要升级他们的密码。由于您可能无法自行设置他们的所有密码,因此您可能想与这些用户联系,让他们升级他们的密码。
要确定谁需要将特权用户(例如,超级用户)的密码升级到SCRAM,可以运行以下SQL:
SELECT
rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS has_upgraded
FROM pg_authid
WHERE rolcanlogin;
该查询查找具有LOGIN特权的用户(即他们可以登录到PostgreSQL集群),并确定他们的密码是否仍存在于PostgreSQL风格的MD5哈希中。
如果has_upgraded为FALSE,则用户需要重新哈希其密码。
注意:在某些极端情况下,上面的查询将注册一个误报(例如,如果您有一个以SCRAM-SHA-256 $开头的纯文本密码),但以上情况很可能起作用。
步骤4:升级密码
通过psql中的\ password命令
使用psql的命令行界面,可以使用\ password命令,即:
\password
或者,如果您想为系统上的其他人设置密码:
\password username
系统将提示您输入新密码。此新密码将转换为SCRAM验证程序,并且此用户的升级将完成。
为什么不使用“ ALTER ROLE user_name PASSWORD 'newpassword';”?
因为上述alter 语句会被PostgreSQL的运行日志记录明文密码。
步骤5:更新pg_hba.conf以仅使用“ scram-sha-256”
这是一个有趣的事实:为了简化升级,即使选择了md5作为身份验证方法,您的应用程序仍然可以执行SCRAM验证!
如果用户帐户的密码已经升级到SCRAM验证程序,则即使md5是身份验证方法,它也将使用SCRAM身份验证!
但是,一旦所有密码都升级,您将需要更新pg_hba.conf文件,并将所有使用md5的条目切换为现在使用scram-sha-256。
首先,检查所有用户是否已升级为可以使用SCRAM,即:
SELECT
rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS has_upgraded
FROM pg_authid
WHERE rolcanlogin;
然后,修改pg_hba.conf文件中的md5整体以使用scram-sha-256,例如,使用上面的示例:
# TYPE DATABASE USER ADDRESS METHOD
local all all scram-sha-256
当上述修改完成后,请reload以便修改生效(不需要restart)
MD5到SCRAM-SHA-256升级操作步骤
下面主要列举MD5到SCRAM-SHA-256升级操作步骤:
1. 前提条件
- 首先确保PostgreSQL实例版本是10及以上版本
1 2 3 4 5 | postgres=# SELECT version(); version --------------------------------------------------------------------------------------------------------- PostgreSQL 13.0 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit (1 row) |
- 连接PostgreSQL数据库的驱动有SCRAM兼容性。PostgreSQL社区已经提供了一个驱动列表,请检查你的客户端驱动是否已支持SCRAM。
2. 配置pg_hba.conf认证
pg_hba.conf配置文件决定了你的客户端怎么连接到PostgreSQL实例,基于升级到SCRAM的目的,请确保你的密码认证方法已经设置为md5,这里估计有人不明白,明明我们现在要把认证方式升级为scram-sha-256,为什么还把认证方式设置为md5呢?PG为了简化从md5方法到新的SCRAM方法的转换,如果在pg_hba.conf中将认证方法设置为md5,但服务器上用户的密码是SCRAM加密的,PG会自动选择基于SCRAM的认证,这样就给到了一个过渡时间,到后面第五步密码全部升级完后再把认证方式修改为scram-sha-256。
#TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 md5
3. 修改password_encryption参数
password_encryption参数决定了密码怎么被hash。默认为md5,修改为scram-sha-256,步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | -- 查询当前参数值 postgres=# SELECT name,setting,source,enumvals FROM pg_settings WHERE name = 'password_encryption'; name | setting | source | enumvals ---------------------+---------+-----------+--------------------- password_encryption | md5 | default | {md5,scram-sha-256} (1 row) -- 修改参数 postgres=# ALTER SYSTEM SET password_encryption TO 'scram-sha-256'; ALTER SYSTEM -- 修改此产生需要重新加载配置 postgres=# SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) -- 修改后参数值 postgres=# SELECT name,setting,source,enumvals FROM pg_settings WHERE name = 'password_encryption'; name | setting | source | enumvals ---------------------+---------------+--------------------+--------------------- password_encryption | scram-sha-256 | configuration file | {md5,scram-sha-256} (1 row) |
4. 查询需要升级密码的用户
查询出哪些还没有升级密码的用户,在下面步骤进行密码升级
1 2 3 4 5 6 7 | postgres=# SELECT rolname FROM pg_authid WHERE rolcanlogin AND rolpassword !~ '^SCRAM-SHA-256\$'; rolname --------- test test1 test2 (3 rows) |
5. 密码升级
使用\password修改密码,系统将提示您输入新密码。此新密码将转换为SCRAM验证程序,并且此用户的升级将完成。这个命令会提示要求输入新口令、对口令加密然后把加密后的口令作为一个ALTER ROLE命令发送到服务器。这确保新口令不会以明文的形式出现在命令历史、服务器日志或者其他地方。不建议直接使用ALTER ROLE进行修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | -- 修改密码 postgres=# \password test Enter new password: Enter it again: -- test的密码已不在下面结果中,代表升级完成 postgres=# SELECT rolname FROM pg_authid WHERE rolcanlogin AND rolpassword !~ '^SCRAM-SHA-256\$'; rolname --------- test1 test2 (2 rows) -- 加密后hash值如下 postgres=# SELECT rolname,rolpassword FROM pg_authid WHERE rolcanlogin; rolname | rolpassword ---------+--------------------------------------------------------------------------------------------------------------------------------------- test1 | md5******************************** test2 | md5******************************** test | SCRAM-SHA-256$4096:OU+ksv2lqF3Hk70cazGf6Q==$L6bD7XY5EsUl+VIn/KVP3cfzns4+AUrSRbtJ4+SGObs=:BPkXFJ+15/n+KLekj04FpBjMHH7Z1mYfA66/dHUfyN0= (3 rows) |
6. 重配置pg_hba.conf认证
一旦所有密码都升级,需要更新pg_hba.conf配置,并将所有使用md5的条目修改为scram-sha-256
1 2 3 4 5 6 7 8 9 10 11 | -- 以下查询语句返回0条,代表所有密码已升级 postgres=# SELECT rolname FROM pg_authid WHERE rolcanlogin AND rolpassword !~ '^SCRAM-SHA-256\$'; rolname --------- (0 rows) -- 修改完配置需要reload配置 postgres=# SELECT pg_reload_conf(); pg_reload_conf ---------------- t (1 row) |
#TYPE DATABASE USER ADDRESS METHOD
host all all 127.0.0.1/32 scram-sha-256
至此所有的PostgreSQL用户账户都已经升级为使用SCRAM进行身份验证!
参考
http://postgres.cn/docs/13/auth-password.html
总结
1、查询密码格式可以使用SQL:select rolname,rolpassword from pg_authid ;
2、数据库参数应该同步修改为password_encryption = scram-sha-256
3、由md5转换为scram-sha-256时,需要重新修改已经存在的密码,否则不能登录。
4、修改pg_hba.conf文件