正在加载,请稍候…

从 MD5 迁移到 SCRAM-SHA-256:PostgreSQL 实战指南

PostgreSQL 密码哈希算法从 MD5 迁移到 SCRAM-SHA-256 的步骤、影响分析与升级方案,包含检测脚本、密码重置策略和回滚方案。

将 PostgreSQL 密码哈希从旧版 MD5 算法迁移到 SCRAM-SHA-256 是一项关键的安全升级。本指南将进行影响分析,并提供分步骤的迁移计划,包括检测脚本、密码重置策略和回滚注意事项。

服务器机架带 PostgreSQL 标志

为什么从 MD5 迁移到 SCRAM-SHA-256?

MD5 密码哈希存在已知漏洞(快速哈希、碰撞攻击)。SCRAM-SHA-256(基于 SHA-256 的加盐挑战响应认证机制)是 PostgreSQL 10+ 的现代标准。它使用加盐、迭代哈希,能够抵抗暴力破解和彩虹表攻击。合规框架(如等级保护)通常要求使用 SCRAM-SHA-256。

了解影响

关键概念

  • password_encryption(在 postgresql.conf 中):控制通过 CREATE USERALTER USER 设置的密码所使用的算法。更改它不会重新哈希现有密码。
  • pg_hba.conf 认证方法:PostgreSQL 10+ 中的 md5 实际上接受同时接受 MD5 和 SCRAM-SHA-256 哈希。scram-sha-256 只接受 SCRAM-SHA-256。
  • 密码存储:哈希存储在 pg_authid.rolpassword 中。MD5 哈希以 md5 开头,SCRAM-SHA-256 哈希以 SCRAM-SHA-256$ 开头。

影响矩阵

变更 效果
password_encryption 改为 scram-sha-256 新密码使用 SCRAM-SHA-256;如果 pg_hba.conf 使用 md5,现有 MD5 密码仍然有效
pg_hba.conf 改为 scram-sha-256 只有 SCRAM-SHA-256 哈希可以认证;MD5 用户将被锁定
不重置密码 切换 pg_hba.confscram-sha-256 后,拥有 MD5 哈希的用户无法登录

分步骤迁移计划

阶段 1:清查与准备

  1. 识别所有具有 MD5 哈希的登录角色
SELECT rolname, rolpassword
FROM pg_authid
WHERE rolpassword LIKE 'md5%'
  AND rolcanlogin = true;
  1. 检查客户端驱动兼容性:确保所有客户端库(psql、JDBC、Npgsql 等)支持 SCRAM-SHA-256。PostgreSQL 10+ 客户端兼容。

  2. 备份 pg_authid

COPY pg_authid TO '/tmp/pg_authid_backup.csv' WITH CSV HEADER;

阶段 2:密码迁移(pg_hba.conf 仍使用 md5

  1. postgresql.conf 中设置 password_encryptionscram-sha-256
password_encryption = scram-sha-256
  1. 重新加载配置
pg_ctl reload
# 或 SQL: SELECT pg_reload_conf();
  1. 重置所有 MD5 用户的密码。对于已知密码的系统用户:
ALTER USER postgres PASSWORD 'admin_password';
ALTER USER replicator PASSWORD 'replication_password';

对于应用用户,从配置文件中收集密码并重置:

# Python 示例
users = {
    'app_user1': 'pwd_from_config',
    'app_user2': 'pwd_from_config',
}
for user, pwd in users.items():
    execute_sql(f"ALTER USER {user} PASSWORD '{pwd}';")
  1. 验证没有 MD5 哈希残留
SELECT rolname, rolpassword FROM pg_authid
WHERE rolpassword LIKE 'md5%' AND rolcanlogin = true;
-- 应返回空行

阶段 3:切换认证方法

  1. 编辑 pg_hba.conf:将所有相关行中的 md5 改为 scram-sha-256

  2. 重新加载配置

pg_ctl reload
  1. 测试登录
psql -U postgres -d postgres

阶段 4:验证

  • 验证所有应用程序连接正常工作。
  • 对于复制用户,如有必要更新 primary_conninfo
  • 确认没有残留的 MD5 哈希:
SELECT rolname FROM pg_authid WHERE rolpassword LIKE 'md5%' AND rolcanlogin = true;

常见陷阱

  • 忘记复制用户:复制角色(例如 replicator)也需要重置密码;否则复制会中断。
  • 跳过客户端兼容性:较旧的驱动(PG10 之前)可能不支持 SCRAM-SHA-256。先升级它们。
  • 认为 password_encryption 会追溯更改现有哈希:它不会。你必须显式重置密码。
  • 没有回滚计划:MD5 哈希无法从 SCRAM-SHA-256 转换回 MD5。保留 pg_authid 的备份。
  • 在所有密码迁移完成之前,在 pg_hba.conf 中使用 scram-sha-256:拥有 MD5 哈希的用户将立即被锁定。

回滚策略

如果需要回退:

  1. 从备份恢复 pg_authid
  2. password_encryption 设置为 md5pg_hba.conf 改回 md5
  3. 重新加载配置。
  4. 再次重置密码(因为 SCRAM-SHA-256 哈希不向后兼容)。

常见问题

如果我更改了 password_encryption 但没有更改 pg_hba.conf,会发生什么?

新密码将使用 SCRAM-SHA-256 哈希,但现有 MD5 密码仍然可用,因为 pg_hba.conf 中的 md5 接受两者。这是一个安全的中间步骤。

我可以在不知道明文密码的情况下将 MD5 哈希转换为 SCRAM-SHA-256 吗?

不能。MD5 哈希是单向的。你必须知道原始密码才能用 SCRAM-SHA-256 重新哈希。

如何处理我不知道密码的应用用户?

选项:

  • 在迁移后强制用户在首次登录时更改密码。
  • 临时为这些用户在 pg_hba.conf 中保留 md5(不合规)。
  • 在迁移前从应用程序配置文件中收集密码(推荐)。

SCRAM-SHA-256 会影响性能吗?

SCRAM-SHA-256 在认证时比 MD5 更耗费 CPU,但对于典型登录率来说,开销可以忽略不计。安全收益远远超过成本。

PostgreSQL 10 之前的版本呢?

SCRAM-SHA-256 从 PostgreSQL 10 开始支持。对于旧版本,请先升级 PostgreSQL。

尝试我们的 Bcrypt 哈希生成器 来了解现代哈希原理。