密码哈希与凭证存储(PBKDF2/Scrypt/Pepper)最佳实践概述安全的密码存储需采用抗暴力猜测的哈希算法、唯一Salt与受控Pepper,支持参数升级与泄露响应流程。哈希配置与版本化type HashParams = { alg: 'pbkdf2' | 'scrypt'; iter?: number; keyLen: number; saltLen: number; scryptN?: number; scryptR?: number; scryptP?: number; version: number }
const CURRENT: HashParams = { alg: 'pbkdf2', iter: 120000, keyLen: 64, saltLen: 16, version: 2 }
生成哈希(PBKDF2/Scrypt)import crypto from 'crypto'
function makeSalt(len: number): string { return crypto.randomBytes(len).toString('hex') }
function derive(password: string, salt: string, pepper: string, params: HashParams): string {
const material = password + pepper
if (params.alg === 'pbkdf2') {
const buf = crypto.pbkdf2Sync(material, salt, params.iter!, params.keyLen, 'sha512')
return buf.toString('hex')
} else {
const buf = crypto.scryptSync(material, salt, params.keyLen, { N: params.scryptN!, r: params.scryptR!, p: params.scryptP! })
return buf.toString('hex')
}
}
type StoredHash = { alg: string; ver: number; iter?: number; N?: number; r?: number; p?: number; keyLen: number; salt: string; hash: string }
function hashPassword(password: string, pepper: string, params = CURRENT): StoredHash {
const salt = makeSalt(params.saltLen)
const hash = derive(password, salt, pepper, params)
return { alg: params.alg, ver: params.version, iter: params.iter, keyLen: params.keyLen, salt, hash }
}
验证与参数升级function verifyPassword(password: string, pepper: string, stored: StoredHash): boolean {
const params: HashParams = stored.alg === 'pbkdf2'
? { alg: 'pbkdf2', iter: stored.iter!, keyLen: stored.keyLen, saltLen: stored.salt.length/2, version: stored.ver }
: { alg: 'scrypt', keyLen: stored.keyLen, saltLen: stored.salt.length/2, scryptN: stored.N!, scryptR: stored.r!, scryptP: stored.p!, version: stored.ver }
const hash = derive(password, stored.salt, pepper, params)
return crypto.timingSafeEqual(Buffer.from(hash, 'hex'), Buffer.from(stored.hash, 'hex'))
}
function needsRehash(stored: StoredHash): boolean { return stored.ver < CURRENT.version }
运维与泄露响应Pepper仅存放在安全服务(KMS/Vault),应用侧不落盘定期评估迭代次数或Scrypt参数,进行无感升级(登录时重算)泄露时强制重置、提升参数并开启MFA与频控通过版本化参数、唯一Salt与Pepper治理,可在大多数Web场景下实现稳健的密码存储。

发表评论 取消回复