1

嗨,我的问题是我已经在 windows azure 服务器端 Javascript 上使用 crypto.pbkdf2 加密了密码我很确定有一个公共库可供您查找。问题是我试图在我的系统上用 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 函数接受一个字符串

4

2 回答 2

0

好吧,孩子们爸爸已经想出了答案……花了足够长的时间……

Buffer(encodedPassword, 'binary').toString('base64')

现在,在 Javascript 方面就足够了,我查看的教程显然不准确.. 缺少“二进制”。

谢谢大家的帮助:)

新年快乐

于 2014-01-14T14:25:34.677 回答
0

我希望凭证是通用的,但尽管使用了 Rfc2898DeriveBytes 和第一次生成的盐,但我无法返回相同的散列密码。

显而易见的东西是哈希算法、盐和迭代计数。您能否确认(两种语言):

  1. 哈希算法
  2. 迭代次数

不明显的是密码的编码和可能的盐。我包括了盐,因为它通常存储为字符串。

为了保持它在语言之间的可移植性,您应该使用 UTF-8。这是因为您可能会遇到默认编码、UTF16-BE、UTF16-LE 或任何数量的其他编码。

在 C# 中,设置为:

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

然后,您将传递utf8_saltandutf8_pass给该PBKDF2函数。

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

于 2014-01-11T05:05:31.790 回答