在Node.js中复现ASP.NET MembershipProvider SHA1哈希算法遇阻求助
问题:Node.js中复现ASP.NET MembershipProvider的SHA1加盐哈希失败
我需要在Node.js中兼容ASP.NET MembershipProvider生成的SHA1加盐哈希密码,但尝试多种方法后均未成功。
测试数据与基础哈希尝试
第一组测试数据:
const passwordPlaintext = 'this-is-the-password' const passwordHash = 'oVj57RdHdLi1rGSx21qnVxj4ewc=' const passwordSalt = '5hz9hys/gdADzfgikgFLYg=='
我按照“盐字节+密码字节拼接后SHA1哈希转base64”的逻辑实现了代码:
function dotnet_membership_password_hash(pass, salt, encoding) { var bytes = Buffer.from(pass || '', encoding) var src = Buffer.from(salt || '', 'base64') var dst = Buffer.alloc(src.length + bytes.length) src.copy(dst, 0, 0, src.length) bytes.copy(dst, src.length, 0, bytes.length) return crypto.createHash('sha1').update(dst).digest('base64') }
结果不符情况
分别尝试utf8和utf16le编码后,结果均与数据库原始哈希不匹配:
oVj57RdHdLi1rGSx21qnVxj4ewc= (原始哈希) pCsR7pToO3UiPNmSO8Xr6lqJo/M= (utf8) ❌ AWxwnQ7JDFavjE8jV1J5qkxvKvA= (utf16le) ❌
第二组测试数据:
const passwordPlaintext = 'password123' const passwordHash = 'twEXsCXaU7YnpXyw0vMUjwmVa8E=' const passwordSalt = '0z9kTO9ksSpd4VUCAH9FVw=='
结果同样不匹配:
twEXsCXaU7YnpXyw0vMUjwmVa8E= (原始哈希) gbUyM/OwMzOCAKRZo42c9Vb8vrA= (utf8) ❌ x5yUPGlqJYOeKuwq4miU7Fwbk+8= (utf16le) ❌
结合machineKey的HMAC尝试
web.config中存在验证密钥配置:
<machineKey validationKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" decryptionKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" decryption="3DES" validation="SHA1" />
我尝试将验证密钥结合到HMAC哈希逻辑中,依然失败:
const dotnet_membership_password_hmachash = function (pass, salt, vKey, encoding) { var key = null var bIn = Buffer.from(pass, encoding) var bSalt = Buffer.from(salt, 'base64') if (vKey.length == bSalt.length) { key = bSalt } else if (vKey.length < bSalt.length) { var bKey = new Buffer(vKey.length) bSalt.copy(bKey, 0, 0, bKey.Length) key = bKey } else { var bKey = new Buffer(vKey.length) for (var iter = 0; iter < bKey.length;) { var len = Math.min(bSalt.length, bKey.length - iter) bSalt.copy(bKey, iter, 0, len) iter += len } key = bKey } return crypto.createHmac('sha1', key).update(bIn).digest('base64') }
C#测试对比
我用C#实现了相同的加盐哈希逻辑,输出结果和Node.js中utf16le编码的结果一致,但仍与数据库原始哈希不符:
using System.IO; using System; using System.Text; using System.Security.Cryptography; class Program { static string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); byte[] src = Convert.FromBase64String(salt); byte[] dst = new byte[src.Length + bytes.Length]; Buffer.BlockCopy(src, 0, dst, 0, src.Length); Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length); HashAlgorithm algorithm = HashAlgorithm.Create("SHA1"); byte[] inArray = algorithm.ComputeHash(dst); return Convert.ToBase64String(inArray); } static void Main() { string pass = "this-is-the-password"; string salt = "5hz9hys/gdADzfgikgFLYg=="; string hash = Program.EncodePassword(pass,salt); Console.WriteLine(hash); // 输出 AWxwnQ7JDFavjE8jV1J5qkxvKvA } }
内容的提问来源于stack exchange,提问作者Adam K Dean
相关产品推荐
相关产品推荐

