Discourse 密码存储系统的当前详细信息可参阅 https://github.com/discourse/discourse/blob/main/docs/SECURITY.md。截至撰写本文时,我们使用 PBKDF2-SHA256 算法,迭代次数为 600,000 次。
在某些情况下,您可能希望将 Discourse 中所有已哈希的密码导出,并导入到另一个系统中。例如,您可能正从 Discourse 内置的身份验证迁移到自定义的 SSO 系统。请记住,无法从数据库中还原原始密码,因此您的目标系统必须能够使用相同的哈希算法及参数进行运算。
密码数据存储在 user_passwords 表中,该表包含 password_hash、password_salt 和 password_algorithm 列。password_algorithm 列存储完整的 PHC 算法前缀(例如 $pbkdf2-sha256$i=600000,l=32$),如果迭代次数随时间增加,该值可能因用户而异。
您可以使用数据浏览器(Data Explorer)以计算机可读格式导出相关信息:
SELECT users.id, users.username, up.password_salt, up.password_hash, up.password_algorithm
FROM users
INNER JOIN user_passwords up ON users.id = up.user_id
WHERE users.id > 0
这将按 Discourse 原生格式导出数据。其中,salt 为十六进制编码,密码哈希值也为十六进制编码。
某些外部系统支持 PHC 字符串格式,该格式旨在以跨算法的方式表示密码哈希函数的输出。对于 pbkdf2-sha256,该字符串包含算法类型、迭代次数、base64 编码的 salt 以及 base64 编码的哈希值。幸运的是,Postgres 可以通过单个查询为我们处理所有这些内容。
若要为每个 Discourse 用户生成 PHC 字符串,您可以使用如下数据浏览器查询:
SELECT users.id, users.username,
concat(
up.password_algorithm,
replace(encode(up.password_salt::bytea, 'base64'), '=', ''),
'$',
replace(encode(decode(up.password_hash, 'hex'), 'base64'), '=', '')
) as phc
FROM users
INNER JOIN user_passwords up ON users.id = up.user_id
WHERE users.id > 0
如果您使用 Auth0,则应使用以下查询:
SELECT
user_emails.email,
users.active as email_verified,
concat(
up.password_algorithm,
replace(encode(up.password_salt::bytea, 'base64'), '=', ''),
'$',
replace(encode(decode(up.password_hash, 'hex'), 'base64'), '=', '')
) as password_hash
FROM users
INNER JOIN user_passwords up ON users.id = up.user_id
INNER JOIN user_emails
ON users.id = user_emails.user_id
AND user_emails.primary IS TRUE
AND users.id > 0
