一 window.crypto来实现密码的哈希转换
在浏览器环境中,使用window.crypto对象结合SubtleCrypto接口来实现密码的哈希转换,通常会使用PBKDF2(Password-Based Key Derivation Function 2)算法,它是一种通过多次迭代来增加破解难度的密码哈希方法。以下是一个示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Hashing</title>
</head>
<body>
<script>
// 待哈希的密码
const password = "mysecretpassword";
// 生成盐值,这里使用16字节的随机值
const salt = new Uint8Array(crypto.getRandomValues(new Uint8Array(16)));
// 迭代次数,一般设置较大的值增加安全性
const iterations = 100000;
// 期望生成的密钥长度(以比特为单位),这里设置为256比特即32字节
const keyLength = 256;
async function hashPassword() {
try {
// 将密码字符串转换为Uint8Array
const encoder = new TextEncoder();
const passwordData = encoder.encode(password);
// 导入密码密钥
const passwordKey = await window.crypto.subtle.importKey(
"raw",
passwordData,
{ name: "PBKDF2" },
false,
["deriveBits"]
);
// 派生密钥
const derivedKey = await window.crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: iterations,
hash: { name: "SHA-256" }
},
passwordKey,
keyLength
);
// 将派生的密钥转换为十六进制字符串
const hashArray = Array.from(new Uint8Array(derivedKey));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
console.log("Salt:", Array.from(salt).map(b => b.toString(16).padStart(2, '0')).join(''));
console.log("Hashed Password:", hashHex);
} catch (error) {
console.error("Error hashing password:", error);
}
}
hashPassword();
</script>
</body>
</html>
在上述代码中:
-
首先定义了密码、盐值、迭代次数和密钥长度等参数。
-
hashPassword函数将密码转换为Uint8Array,并使用subtle.importKey导入密码密钥。
-
然后通过subtle.deriveBits方法基于PBKDF2算法和设置的参数派生密钥。
-
最后将派生的密钥转换为十六进制字符串进行展示,同时也展示了生成的盐值。
二 使用crypto模块实现密码的哈希转换
在Node.js环境中,crypto模块提供了丰富的加密功能,使用它实现密码哈希转换,常见的是采用pbkdf2算法,这是一种基于密码的密钥派生函数,通过多次迭代来增加安全性。以下是示例代码:
const crypto = require('crypto');
// 待哈希的密码
const password = 'your_password_here';
// 生成随机盐值,建议盐值长度足够长以增强安全性
const salt = crypto.randomBytes(16).toString('hex');
// 迭代次数,通常设置较大的值来增加破解难度,这里设置为100000次
const iterations = 100000;
// 生成密钥的长度(以字节为单位),这里设置为64字节
const keylen = 64;
// 哈希算法,这里使用SHA256
const digest ='sha256';
// 使用pbkdf2Sync方法进行同步哈希计算
const hashedPassword = crypto.pbkdf2Sync(password, salt, iterations, keylen, digest).toString('hex');
console.log('盐值(Salt):', salt);
console.log('哈希后的密码(Hashed Password):', hashedPassword);
上述代码中:
-
首先引入crypto模块。
-
定义了要哈希的密码,生成随机盐值,设置迭代次数、生成密钥长度和哈希算法。
-
然后调用crypto.pbkdf2Sync方法,传入密码、盐值、迭代次数、密钥长度和哈希算法,得到哈希后的密码。
-
最后打印出盐值和哈希后的密码。
在实际应用中,将盐值和哈希后的密码存储起来,当用户登录验证时,使用相同的盐值和算法对用户输入的密码进行哈希,再对比哈希值是否一致。