dis*_*ted 9 javascript cryptography password-hash node.js scrypt
仅使用内置crypto模块在 Node.js 中实现密码哈希和验证的最佳方法是什么?基本上需要什么:
function passwordHash(password) {} // => passwordHash
function passwordVerify(password, passwordHash) {} // => boolean
Run Code Online (Sandbox Code Playgroud)
人们通常使用bcrypt或其他第三方库来实现此目的。我想知道内置crypto模块是否足够大,至少可以满足所有基本需求?
Yil*_*maz 18
import { scrypt, randomBytes, timingSafeEqual } from "crypto";
import { promisify } from "util";
// scrypt is callback based so with promisify we can await it
const scryptAsync = promisify(scrypt);
Run Code Online (Sandbox Code Playgroud)
散列过程有两种方法。第一种方法,您对密码进行哈希处理,第二种方法,您需要将新的登录密码与存储的密码进行比较。我用打字稿详细写下所有内容
export class Password {
static async hashPassword(password: string) {
const salt = randomBytes(16).toString("hex");
const buf = (await scryptAsync(password, salt, 64)) as Buffer;
return `${buf.toString("hex")}.${salt}`;
}
static async comparePassword(
storedPassword: string,
suppliedPassword: string
): Promise<boolean> {
// split() returns array
const [hashedPassword, salt] = storedPassword.split(".");
// we need to pass buffer values to timingSafeEqual
const hashedPasswordBuf = Buffer.from(hashedPassword, "hex");
// we hash the new sign-in password
const suppliedPasswordBuf = (await scryptAsync(suppliedPassword, salt, 64)) as Buffer;
// compare the new supplied password with the stored hashed password
return timingSafeEqual(hashedPasswordBuf, suppliedPasswordBuf);
}
}
Run Code Online (Sandbox Code Playgroud)
测试一下:
Password.hashPassword("123dafdas")
.then((res) => Password.comparePassword(res, "123edafdas"))
.then((res) => console.log(res));
Run Code Online (Sandbox Code Playgroud)
const password = "my_password";
// Creating a unique salt for a particular user
const salt = crypto.randomBytes(16).toString('hex');
// Hash the salt and password with 1000 iterations, 64 length and sha512 digest
const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, 'sha512').toString('hex');
Run Code Online (Sandbox Code Playgroud)
将用户的salt和存储在数据库中。hash
const re_entered_password = "my_password";
// To verify the same - salt (stored in DB) with same other parameters used while creating hash (1000 iterations, 64 length and sha512 digest)
const newHash = crypto.pbkdf2Sync(re_entered_password, salt, 1000, 64, 'sha512').toString('hex');
// check if hash (stored in DB) and newly generated hash (newHash) are the same
hash === newHash;
Run Code Online (Sandbox Code Playgroud)