在C#和NodeJS中生成相同的PBKDF2密钥

时间:2015-02-10 20:48:16

标签: c# node.js encryption pbkdf2

我尝试使用NodeJS加密库和C#Rfc2898DeriveBytes生成相同的密码哈希。使用NodeJ生成的salt时,C#实现不会生成相同的密钥。我做错了什么?

nodeJS中生成的salt和hash:

Salt: GJNw/wzXZxEdXrheqo322mf0x+92AeAuAHH48iiGZ+A=
Hash: w6fCpsKxw78Fw4pMFk5Zw6vDin7CnG5VwpUWBSjCo8OSOTJ6w47Cv8KWcjIpwoA=

在C#中生成的哈希:

1G84mPkY78nsQ2BzO/qUPd+e0Lobrz7ZLzc+p7Zh0o8=

我的C#测试代码如下:

public const int HASH_BYTE_SIZE = 32; 
public const int PBKDF2_ITERATIONS = 1000;

public static string HashPassword(string password, string salt)
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            byte[] saltBytes = Convert.FromBase64String(salt);

            var pbkdf2 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, PBKDF2_ITERATIONS);
            var hash = pbkdf2.GetBytes(HASH_BYTE_SIZE);

            return Convert.ToBase64String(hash);
        }

static void Main(string[] args)
        {
            string salt = "GJNw/wzXZxEdXrheqo322mf0x+92AeAuAHH48iiGZ+A=";
            string plainTextPsw = "12345";

            string hashedPsw = PasswordHash.HashPassword(plainTextPsw, salt);

            Console.WriteLine(hashedPsw);
            Console.ReadLine();
        }

和NodeJs:

var crypto = require('crypto');
var iterations = 1000;
var bytes = 32;

exports.createSalt = function () {
    return new Buffer(crypto.randomBytes(bytes)).toString('base64');
}

exports.hash = 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);
        }
    });
}

1 个答案:

答案 0 :(得分:0)

Node.js代码中发生了一些错误的转换,产生了无效的结果。

首先,"盐"传递给pbkdf2函数应该是随机字节,不应用任何转换。但是,在这种情况下,字节用Base64编码为文本,并且该文本中的字符被Node.js用作盐。

然后,派生密钥应使用Base64直接编码为文本。但在这里,密钥的字节被视为字符;使用UTF-8编码将此字符串转换为不同字节的新字符串。然后使用Base64对此编码进行编码,以产生最终的错误结果。