为什么 nodeJs bcrypt 和 dotNet 版本的哈希结果之间存在差异

Why is there a difference between hash results of nodeJs bcrypt and dotNet version

所以生成的哈希值(使用相同数量的盐轮)是不同的,这是我使用的:

NodeJs 实现: https://www.npmjs.com/package/bcrypt

dotNet 实现: http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx

两个结果哈希值都以 a$ 开头,表示我们使用相同的 bcrypt 版本和相同的加盐轮数,但相同输入的结果不同。

有人知道为什么吗?

所以前 3 次我使用 BCrypt.CheckPassword 检查散列密码是否匹配,接下来 3 次我与 nodeJs

中生成的散列进行比较
            string password = "SomePassword";

            byte[] bytes = Encoding.Default.GetBytes(password);
            password = Encoding.UTF8.GetString(bytes);


            //string candidate = "a$zDG1M72eRg9FAeSEJrVNNeJYh0Fa3DsuAP9nBa.IDgbDQLOw.525O";
            string candidate = "SomePassword";

            Console.OutputEncoding = System.Text.Encoding.UTF8;

            string hashed;
            bool matches;

            hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
            Console.WriteLine(hashed);
            matches = BCrypt.CheckPassword(candidate, hashed);
            Console.WriteLine(matches.ToString());

            hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
            Console.WriteLine(hashed);
            matches = BCrypt.CheckPassword(candidate, hashed);
            Console.WriteLine(matches.ToString());

            hashed = BCrypt.HashPassword(password, BCrypt.GenerateSalt(12));
            Console.WriteLine(hashed);
            matches = BCrypt.CheckPassword(candidate, hashed);
            Console.WriteLine(matches.ToString());


            matches = BCrypt.CheckPassword(candidate, "a$wnCnB5lEX8XT.QUnYVmzQ.pCC03QobNZ2uxDz17BASn03maFfnWGq");
            Console.WriteLine(matches.ToString());
            matches = BCrypt.CheckPassword(candidate, "a$eYbwrN6P.BYc.4NncivrQeOEGeXBKGwPcfnEGRSOgKJfWzZoO9auu");
            Console.WriteLine(matches.ToString());
            matches = BCrypt.CheckPassword(candidate, "a$kKaPRy9u9w.1Jjh/aG5PfuT3IohSDFIG/1B2i7twE9huGwAR/kMTm");
            Console.WriteLine(matches.ToString());

            Console.ReadKey();

输出:

a$Yl3IO09nJ.dTc621yjvH5uUz7TOz/UjziEI5lZuNW6dED.K0GlOSC
True
a$t8ruHd0FrKNazO/t3j0dP.KG683vjyqiE7lErC7iQfwAxK6pLASG.
True
a$ZhbyzBh956Mxps9Y5pho9e.age8oj3VsJjf4ScWpv0nilSNx00Axq
True
False
False
False

每次检查时,您使用的是不同的盐,这些盐包含在密码哈希中,因此这种方法永远行不通。

你应该做的是使用BCrypt.Verify(password, hash),它将使用相同的版本、salt 轮数和salt 来验证密码是否有效。

密码哈希中似乎还有多余的空格...

var password = "Dule1Savic";

var hash = "a$rmrr0tLPKOpX7BI1XEZj3.rn8US.J8Cm13A/eHm3uzg70XXzaMHSi";

var isMatch = BCrypt.Net.BCrypt.Verify(password, hash);

Console.WriteLine(isMatch); // True