Discourse のパスワード保存システムに関する現在の詳細は、discourse/docs/SECURITY.md at main · discourse/discourse · GitHub で確認できます。執筆時点では、600,000 回のイテレーションで PBKDF2-SHA256 を使用しています。
状況によっては、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 は hex エンコードされ、パスワードハッシュも hex エンコードされます。
一部の外部システムは、パスワードハッシュ関数の出力をアルゴリズムを跨いで表現することを目的とした PHC ストリング形式 をサポートしています。pbkdf2-sha256 の場合、このストリングにはアルゴリズムの種類、イテレーション数、base64 エンコードされた Salt、base64 エンコードされたハッシュが含まれます。幸いにも、Postgres は単一のクエリでこれらすべてを処理できます。
各 Discourse ユーザーに対して PHC ストリングを生成するには、Data Explorer で以下のようなクエリを使用できます。
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