I did as you asked. The password is swordfish#98765
.
Database entry:
discourse=> SELECT password_hash, salt, password_algorithm FROM users WHERE id=1;
password_hash | salt | password_algorithm
------------------------------------------------------------------+----------------------------------+-------------------------------
db3f0829e66336323e81110a1792a76000b9c60605e1fa6964797ea1b07c33c6 | 0d079078e220158011afaf497794166d | $pbkdf2-sha256$i=600000,l=32$
(1 row)
OpenSSL:
/var/discourse# openssl kdf \
> -kdfopt pass:'swordfish#98765' \
> -kdfopt salt:0d079078e220158011afaf497794166d \
> -kdfopt digest:SHA2-256 \
> -kdfopt iter:600000 \
> -keylen 32 \
> PBKDF2 \
> | tr -d : | tr '[:upper:]' '[:lower:]'
db3f0829e66336323e81110a1792a76000b9c60605e1fa6964797ea1b07c33c6
Go code:
var userId int
var hash string
var salt string
var active bool
row := s.Database.QueryRow(`
SELECT u.id, u.password_hash, u.salt, u.active
FROM users AS u
INNER JOIN user_emails AS ue ON u.id = ue.user_id
WHERE ue.email = $1;`,
email,
)
if err := row.Scan(&userId, &hash, &salt, &active); err != nil {
// error handling...
}
hashBytes, err := hex.DecodeString(hash)
if err != nil {
// error handling...
}
saltBytes, err := hex.DecodeString(salt)
if err != nil {
// error handling...
}
key := pbkdf2.Key([]byte(password), saltBytes, 600000, 32, sha256.New)
fmt.Printf("salt: %v\n", salt)
fmt.Printf("hash: %v\n", hash)
fmt.Printf("hex.EncodeToString(key): %v\n", hex.EncodeToString(key))
Output of the above code:
salt: 0d079078e220158011afaf497794166d
hash: db3f0829e66336323e81110a1792a76000b9c60605e1fa6964797ea1b07c33c6
hex.EncodeToString(key): b378c12d96ac62a6099fc674d334f0793e6294f7927da0badc811e794a960802