pbkdf2计算在C#和JavaScript之间不一致

时间:2014-01-11 04:21:02

标签: c# javascript encryption pbkdf2

我的问题是我在Windows Azure服务器端使用crypto.pbkdf2加密了密码Javascript我非常确定您可以查找公共图书馆。问题是我试图在我的系统上用C#加密相同的密码,因为我希望凭证是通用的,但是尽管使用了Rfc2898DeriveBytes并且第一次生成的盐我无法返回到相同的哈希密码。

感谢您的帮助:)

function hash(text, salt, callback) {
  crypto.pbkdf2(text, salt, iterations, bytes, function(err, derivedKey){
    if (err) { callback(err); }
    else {
      var h = new Buffer(derivedKey).toString('base64');
      callback(null, h);
    }
  });
}

和C#代码:

byte[] salt = Convert.FromBase64String(user.salt);
using (var deriveBytes = new System.Security.Cryptography.Rfc2898DeriveBytes(password, salt, 1000))
{
  byte[] newKey = deriveBytes.GetBytes(32);

  // user is the user object drawn from the database in existence
  if (Convert.ToBase64String(newKey).Equals(user.password))
  {
    FormsAuthentication.RedirectFromLoginPage(Request.Form["username"], false);
  }
}

由C#生成的十六进制= 3lRSQF5ImYlQg20CGFy2iGUpWfdP5TD0eq2cTHhLono =

由JS生成的十六进制= w4PDh8K6YMKGwr3DgcObRsOsFFUgDMOJw5PCnkdAwrTCgcOOV8OCKMKFdcKRwrLCqMK2VA ==

JS生成的盐并用于= / Ij0hgDsvAC1DevM7xkdGUVlozdCxXVd0lgfK2xEh2A =

以上所有信息均采用base64格式

另一件可能有用的事情

item.salt = new Buffer(crypto.randomBytes(bytes)).toString('base64'); crypto.pbkdf2(text, salt, iterations, bytes, function(err, derivedKey){

表示JS函数接受字符串

2 个答案:

答案 0 :(得分:0)

  

我希望凭据是通用的但是尽管使用了Rfc2898DeriveBytes并且第一次生成了盐,我无法恢复到相同的哈希密码。

显而易见的是哈希算法,盐和迭代计数。你能确认(两种语言):

  1. 哈希算法
  2. 迭代次数
  3. 非显而易见的是密码和盐的编码。我把盐包括在内,因为它经常以字符串形式存储。

    为了在语言中保持可移植性,您应该使用UTF-8。那是因为您可能会遇到默认编码,UTF16-BE,UTF16-LE或任何其他编码。

    在C#中,设置为:

    byte[] utf8_salt = Encoding.UTF8.GetBytes(salt);
    byte[] utf8_pass = Encoding.UTF8.GetBytes(password);
    

    然后,您会将utf8_saltutf8_pass传递给PBKDF2函数。

    我不知道如何在Javascript中做同样的事情。

答案 1 :(得分:0)

好孩子爸爸已经找到了答案......花了足够长的时间......

Buffer(encodedPassword, 'binary').toString('base64')
Javascript方面的

就足够了,我看过的教程显然不准确..'二进制'缺失了。

谢谢大家的帮助:)

新年快乐