简体   繁体   中英

pbkdf2 computation not consistent between C# and JavaScript

Hi my question is I've Encrypted a password with crypto.pbkdf2 on windows azure server side Javascript I'm pretty sure that there is a public library which you can look up. The problem is I'm trying to encrypt the same password in C# on my system because I want the credentials to be universal but despite using Rfc2898DeriveBytes and the salt generated the first time I'm not able to get back to the same hashed password.

Thank you for your help :)

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);
    }
  });
}

And the C# code:

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);
  }
}

hex generated by C# = 3lRSQF5ImYlQg20CGFy2iGUpWfdP5TD0eq2cTHhLono=

hex generated by JS = w4PDh8K6YMKGwr3DgcObRsOsFFUgDMOJw5PCnkdAwrTCgcOOV8OCKMKFdcKRwrLCqMK2VA==

Salt generated by JS and used at both = /Ij0hgDsvAC1DevM7xkdGUVlozdCxXVd0lgfK2xEh2A=

All the above info is in base64 format

Another thing that might be useful

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

which means the JS function accepts a string

I want the credentials to be universal but despite using Rfc2898DeriveBytes and the salt generated the first time I'm not able to get back to the same hashed password.

The obvious stuff is hash algorithm, salt, and iteration count. Can you confirm (for both languages):

  1. the hash algorithm
  2. the salt
  3. the iteration count

The non-obvious is the encoding of the password and possibly salt. I included the salt because its often stored as a string.

To keep it portable among languages, you should use UTF-8. That's because you could encounter a default encoding, a UTF16-BE, UTF16-LE or any number of other encoding.

In C#, the setup would be:

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

You would then pass utf8_salt and utf8_pass to the PBKDF2 function.

I don't know how to do the same in Javascript.

Alright kids daddy has figured out the answer.. took long enough..

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

on Javascript side will suffice now the tutorial I looked at was clearly not accurate.. the 'binary' was missing.

Thank you all for the help :)

and happy new year

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM