// 挂载到 window 对象的方法 window.passwordUtils = { /** * 哈希密码(返回 Promise) * @param {string} password - 明文密码 * @returns {Promise} Base64 格式的盐值+哈希值 */ hashPassword: async function(password) { const encoder = new TextEncoder(); // 生成随机盐值 (16字节) const salt = crypto.getRandomValues(new Uint8Array(16)); // 配置 PBKDF2 参数 const keyMaterial = await crypto.subtle.importKey( 'raw', encoder.encode(password), { name: 'PBKDF2' }, false, ['deriveBits'] ); // 生成哈希 const derivedKey = await crypto.subtle.deriveBits( { name: 'PBKDF2', salt: salt, iterations: 100000, hash: 'SHA-256' }, keyMaterial, 256 // 输出长度 ); // 合并盐值+哈希值并转为 Base64 const hashArray = new Uint8Array(derivedKey); const combined = new Uint8Array(salt.length + hashArray.length); combined.set(salt); combined.set(hashArray, salt.length); return btoa(String.fromCharCode(...combined)); }, /** * 验证密码(返回 Promise) * @param {string} password - 待验证密码 * @param {string} storedHash - 存储的 Base64 哈希值 * @returns {Promise} 是否匹配 */ verifyPassword: async function(password, storedHash) { const encoder = new TextEncoder(); // 解码 Base64 获取盐值和原哈希 const decoded = Uint8Array.from(atob(storedHash), c => c.charCodeAt(0)); const salt = decoded.slice(0, 16); const originalHash = decoded.slice(16); // 重新计算哈希 const keyMaterial = await crypto.subtle.importKey( 'raw', encoder.encode(password), { name: 'PBKDF2' }, false, ['deriveBits'] ); const newHash = await crypto.subtle.deriveBits( { name: 'PBKDF2', salt: salt, iterations: 100000, hash: 'SHA-256' }, keyMaterial, 256 ); // 比较哈希值 const newHashArray = new Uint8Array(newHash); return newHashArray.length === originalHash.length && newHashArray.every((val, i) => val === originalHash[i]); } }; // 控制台测试示例(可直接复制到控制台) /* (async () => { // 哈希测试 const hash = await window.passwordUtils.hashPassword('mypassword'); console.log('Hashed:', hash); // 验证测试 const isValid = await window.passwordUtils.verifyPassword('mypassword', hash); console.log('Verify result:', isValid); // 应输出 true const isInvalid = await window.passwordUtils.verifyPassword('wrongpass', hash); console.log('Wrong password test:', isInvalid); // 应输出 false })(); */