PHP的SSHA密码加解密函数转Node.js crypto实现问题
我来帮你解决这个问题!你的Node.js代码和PHP原函数的核心逻辑没对齐,所以结果不一致,我给你拆解下差异并写出完全匹配的实现:
问题分析
你的Node.js代码主要有几个关键偏差:
- PHP中
sha1($password . $salt, true)返回的是原始二进制数据,而你没有处理这个二进制输出,直接用了字符串形式的摘要 - PHP是把二进制SHA1结果和salt字符串拼接后再Base64编码,你的代码完全没做这个拼接步骤
- 生成salt的逻辑也和PHP不一致,而且错误地把salt传给了
createHash的第二个参数(这个参数是配置项,不是salt)
正确的Node.js实现
首先确保你引入了Node.js的crypto模块,然后实现和PHP逻辑完全一致的两个函数:
const crypto = require('crypto'); // 对应PHP的hashSSHA函数 function hashSSHA(password) { // 生成和PHP逻辑一致的salt:随机数SHA1后取前10位 const randomStr = crypto.randomBytes(4).toString(); // 模拟PHP rand()的随机数 const salt = crypto.createHash('sha1').update(randomStr).digest('hex').substring(0, 10); // 计算password+salt的SHA1原始二进制数据(对应PHP的sha1(..., true)) const sha1Binary = crypto.createHash('sha1').update(password + salt).digest(); // 拼接二进制SHA1结果和salt,再转Base64编码 const encryptedPassword = Buffer.concat([sha1Binary, Buffer.from(salt)]).toString('base64'); return { salt, encrypted: encryptedPassword }; } // 对应PHP的checkhashSSHA函数 function checkhashSSHA(salt, password) { const sha1Binary = crypto.createHash('sha1').update(password + salt).digest(); const hash = Buffer.concat([sha1Binary, Buffer.from(salt)]).toString('base64'); return hash; }
验证测试
你可以用下面的代码测试,确保和PHP生成的结果一致:
// 测试示例 const testPassword = 'hello123'; const hashResult = hashSSHA(testPassword); console.log('生成的Salt:', hashResult.salt); console.log('加密后的密码:', hashResult.encrypted); // 验证密码 const verifyHash = checkhashSSHA(hashResult.salt, testPassword); console.log('验证是否匹配:', verifyHash === hashResult.encrypted); // 输出 true
关键细节说明
- 生成salt时,用
crypto.randomBytes(4)生成随机数据,模拟PHP的rand(),然后SHA1取十六进制字符串再截前10位,和PHP逻辑完全对齐 digest()无参数时返回Buffer,对应PHP中sha1函数的true参数(返回原始二进制)Buffer.concat用来拼接二进制SHA1结果和salt的Buffer,再转Base64,和PHP的base64_encode(sha1(..., true).$salt)行为完全一致
内容的提问来源于stack exchange,提问作者Rutul Patel
相关产品推荐
相关产品推荐

