什么是 PHP 哈希函数的 Node.js 等效项(包括盐和原始输出)?

afo*_*tad 2 javascript php authentication encryption node.js

我的同事有一个存储帐户信息的数据库;帐户的 SHA256 散列密码和盐值作为原始二进制数据(blob)存储在列中。

密码在 PHP 中使用这个散列(true 表示原始输出):

hash("sha256", $salt . $password, true);
Run Code Online (Sandbox Code Playgroud)

我正在尝试在 Node.js 服务器上实现身份验证,该服务器必须从 PHP 取回存储在数据库中的相同散列密码,这似乎不起作用:

/**
 * Validates a password sent by an end user by comparing it to the 
 * hashed password stored in the database. Uses the Node.js crypto library.
 *
 * @param password The password sent by the end user.
 * @param dbPassword The hashed password stored in the database.
 * @param dbSalt The encryption salt stored in the database.
 */
function validatePassword(password, dbPassword, dbSalt) {
    // Should the dbSalt be a Buffer, hex, base64, or what?
    var hmac = crypto.createHmac("SHA256", dbSalt);
    var hashed = hmac.update(password).digest('base64');
    console.log("Hashed user password: " + hashed);
    console.log("Database password: " + dbPassword.toString('base64'));
    return hashed === dbPassword;
}
Run Code Online (Sandbox Code Playgroud)

afo*_*tad 5

经过大量实验,我找到了解决方案。

/**
 * Encrypts a password using sha256 and a salt value.
 *
 * @param password The password to hash.
 * @param salt The salt value to hash with.
 */
function SHA256Encrypt(password, salt) {
    var saltedpassword = salt + password;
    var sha256 = crypto.createHash('sha256');
    sha256.update(saltedpassword);
    return sha256.digest('base64');
}

/**
 * Validates a password sent by an end user by comparing it to the
 * hashed password stored in the database.
 *
 * @param password The password sent by the end user.
 * @param dbPassword The hashed password stored in the database, encoded in Base64.
 * @param dbSalt The encryption salt stored in the database. This should be a raw blob.
 */
function validatePassword(password, dbPassword, dbSalt) {
    var hashed = SHA256Encrypt(password, dbSalt.toString('binary'));
    return hashed === dbPassword;
}
Run Code Online (Sandbox Code Playgroud)

不过,感谢 TravisO,他让我走上了正确的道路。

  • 请**不要**使用 SHA 哈希来存储密码。您应该使用专门为密码设计的东西,例如 [bcrypt](http://codetheory.in/using-the-node-js-bcrypt-module-to-hash-and-safely-store-passwords/)。每秒有可能烧毁数十亿个 SHA256 编码的密码。加盐有帮助,但比你想象的要少得多。如果您正在与现有的 PHP 应用程序配合,您会有点陷入困境,但即使 PHP 也支持 bcrypt。 (2认同)