First of all I read this Hashing a password using SHA256 and .NET/Node.js and it didn't help me.
I have to verify passwords hashes created in ASP.NET in node.js environment. I was told that passwords are generated using this algorithm: What is default hash algorithm that ASP.NET membership uses?.
I have example password hash and salt (first line is password and second line is salt):
"Password": "jj/rf7OxXM263rPgvLan4M6Is7o=",
"PasswordSalt": "/Eju9rmaJp03e3+z1v5s+A==",
I know that hash algorithm is SHA1
and I know that above hash is generated for input test123
. However I can't reproduce hashing algorithm to get same hash for this input. What I tried:
Password = "jj/rf7OxXM263rPgvLan4M6Is7o="
PasswordSalt = "/Eju9rmaJp03e3+z1v5s+A=="
crypto = require("crypto")
sha1 = crypto.createHash("sha1")
PasswordSalt = new Buffer(PasswordSalt, 'base64').toString('utf8')
sha1.update(PasswordSalt+"test123", "utf8")
result = sha1.digest("base64")
console.log(Password)
console.log(result)
Result is:
jj/rf7OxXM263rPgvLan4M6Is7o=
xIjxRod4+HVYzlHZ9xomGGGY6d8=
I was able to get working C# algorithm:
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 = "test123";
string salt = "/Eju9rmaJp03e3+z1v5s+A==";
string hash = Program.EncodePassword(pass,salt);
Console.WriteLine(hash);
// outputs jj/rf7OxXM263rPgvLan4M6Is7o=
}
}
So now it is just a matter of porting this algorithm to node.js. The problem is that c# somehow magically operates on bytes and I don't know how to do it in node. Consider following code (it does not use any salt - it just creates base64 sha1 from password:
crypto = require("crypto")
pass = 'test123'
sha1 = crypto.createHash("sha1")
buf = new Buffer( pass, 'utf8')
sha1.update(buf)
result = sha1.digest("base64")
console.log(result)
// outputs cojt0Pw//L6ToM8G41aOKFIWh7w=
And in c#
using System.Text;
using System.Security.Cryptography;
string pass = "test123";
byte[] bytes = Encoding.Unicode.GetBytes(pass);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(bytes);
string hash = Convert.ToBase64String(inArray);
Console.WriteLine(hash);
// outputs Oc/baVMs/zM28IqDqsQlJPQc1uk=
I need code in node.js that will return same value as code in c#. Any ideas?
Password hashing means passing a plain text password through a hashing algorithm to generate a unique value. Some examples of hashing algorithms are bcrypt, scrypt, and SHA. The downside of hashing is that it is predictable. Every time you pass the same input to a hashing algorithm, it will generate the same output.
To hash a password use bcrypt. hash(plainTextPassword, salt, callback) which returns a promise if no callback is passed. To verify plain text password with hashed password use bcrypt. compare(plainTextPassword, hashedPassword, callback) which also returns a promise if no callback is passed.
The bcrypt hashing function allows us to build a password security platform that scales with computation power and always hashes every password with a salt.
BCrypt Algorithm is used to hash and salt passwords securely. BCrypt permits building a password security stage that can advance nearby hardware innovation to guard against dangers or threats in the long run, like attackers having the computing power to guess passwords twice as quickly.
I finally found the right answer here: https://gist.github.com/PalmerEk/1191651 (with little change from 'ucs2' to 'utf16le'):
function dotnet_membership_password_hash(pass, salt)
{
var bytes = new Buffer(pass || '', 'utf16le');
var src = new Buffer(salt || '', 'base64');
var dst = new Buffer(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');
}
there is a nodejs module which does all the magic for you. No function on stackoverflow worked in my case, but this module works:
https://www.npmjs.com/package/aspnet-identity-pw
var passwordHasher = require('aspnet-identity-pw');
var hashedPassword = passwordHasher.hashPassword('SomePassword');
var isValid = passwordHasher.validatePassword('SomePassword', hashedPassword);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With