You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 11:24:55