【问题标题】:how to recreate the .net membership hmacsha1 hash in javascript如何在 javascript 中重新创建 .net 成员资格 hmacsha1 哈希
【发布时间】:2013-01-11 10:22:16
【问题描述】:

我正在尝试在 javascript 函数中从 .net 成员资格提供程序中重现相同的 hmacsha1 哈希和 base64 编码。我试过使用 crypto-js 并得到不同的结果。 .net 代码会将“test”散列为“W477AMlLwwJQeAGlPZKiEILr8TA="

这是 .net 代码

string password = "test";
HMACSHA1 hash = new HMACSHA1();
hash.Key = Encoding.Unicode.GetBytes(password);
string encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));

这是我尝试使用不会产生相同输出的 crypto-js 的 javascript 方法

var hash = CryptoJS.HmacSHA1("test", "");
var encodedPassword = CryptoJS.enc.Base64.stringify(hash);

如何让我的 javascript 哈希与从 .net 生成的哈希相匹配。

【问题讨论】:

    标签: javascript hash asp.net-membership cryptojs


    【解决方案1】:
    //not sure why crypt-js's utf16LE function doesn't give the same result
    //words = CryptoJS.enc.Utf16LE.parse("test");
    //utf16 = CryptoJS.enc.Utf16LE.stringify("test");
    
    function str2rstr_utf16le(input) {
      var output = [],
          i = 0,
          l = input.length;
    
      for (; l > i; ++i) {
        output[i] = String.fromCharCode(
          input.charCodeAt(i)        & 0xFF,
          (input.charCodeAt(i) >>> 8) & 0xFF
        );
      }
    
      return output.join('');
    }
    
    var pwd = str2rstr_utf16le("test");
    var hash = CryptoJS.HmacSHA1(pwd, pwd);
    
    var encodedPassword = CryptoJS.enc.Base64.stringify(hash);
    alert(encodedPassword);
    

    【讨论】:

      【解决方案2】:

      您没有在 .NET 中指定密钥:

      var secretKey = "";
      var password = "test";
      
      var enc = Encoding.ASCII;
      System.Security.Cryptography.HMACSHA1 hmac = new System.Security.Cryptography.HMACSHA1(enc.GetBytes(secretKey));
      hmac.Initialize();
      
      byte[] buffer = enc.GetBytes(password);
      var encodedPassword = Convert.ToBase64String(hmac.ComputeHash(buffer));
      

      编辑:正如@Andreas 提到的,你的问题是编码。所以你只需要在你自己的代码中用ANSI替换UTF:

      string password = "test";
      System.Security.Cryptography.HMACSHA1 hash = new System.Security.Cryptography.HMACSHA1();
      hash.Key = Encoding.ASCII.GetBytes("");
      string encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.ASCII.GetBytes(password)));   
      

      【讨论】:

      • 他使用password 作为密钥和消息。由于编码不同(ASCII 而不是Unicode),您的解决方案只会给出正确的结果 - 这是真正的问题。
      • 你是对的。我不知何故完全错过了他如何设置钥匙(错误地)。
      • .net 方法是 Umbraco 中现有的功能,我无法修改,所以很遗憾我无法更改它。我只能尝试在 javascript 中复制它。
      • 所以看起来不同之处在于crypto-js使用utf-8编码散列,而.net库使用utf-16
      • 难道你不只是这种怪事,不是你的错,但很容易让你倒退一天? :) 你的答案真的是解决方案吗?
      猜你喜欢
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多