最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Django pbkdf2_sha256 JS implementation - Stack Overflow

programmeradmin2浏览0评论

I have a database from django and I want to work with it from Node.js. I have a task: authenticate users. Known from database: algorithm pbkdf2_sha256, salt, 10000 iterations and base64-encoded hash. What steps I must to do in JS to encode some password to given base64-hash?

UPD: found the solution in here: python (django) hashlib vs Nodejs crypto but Django-generated hash and JS-generated hash not match...
Django generate next:

pbkdf2_sha256$10000$NmzpPCQiTe2R$U8ipSsOy3Xz7FwWDHdH/dTei8Xh4Q7NGtdzrCacSfvo=

JS:

pbkdf2_sha256$10000$NmzpPCQiTe2R$w4jCgWjDilrDmcOBd8K+I8OdwpkKwoVQZMKWH3FvYcKoAMKcwqlewobDocOEGMKZfQ==

Password: Simple123

I have a database from django and I want to work with it from Node.js. I have a task: authenticate users. Known from database: algorithm pbkdf2_sha256, salt, 10000 iterations and base64-encoded hash. What steps I must to do in JS to encode some password to given base64-hash?

UPD: found the solution in here: python (django) hashlib vs Nodejs crypto but Django-generated hash and JS-generated hash not match...
Django generate next:

pbkdf2_sha256$10000$NmzpPCQiTe2R$U8ipSsOy3Xz7FwWDHdH/dTei8Xh4Q7NGtdzrCacSfvo=

JS:

pbkdf2_sha256$10000$NmzpPCQiTe2R$w4jCgWjDilrDmcOBd8K+I8OdwpkKwoVQZMKWH3FvYcKoAMKcwqlewobDocOEGMKZfQ==

Password: Simple123

Share Improve this question edited May 23, 2017 at 12:33 CommunityBot 11 silver badge asked Jul 9, 2013 at 9:21 SoWaSoWa 3144 silver badges12 bronze badges 1
  • Did you try to get the same number of bytes from the PBKDF? Getting 49 bytes in return is a bit strange if you did not specify that number. Also make sure you use the same character-encoding of the password in both functions - the character encoding of PBKDF2 is not specified (although UTF-8 is hinted at). – Maarten Bodewes Commented Jul 26, 2013 at 16:20
Add a comment  | 

4 Answers 4

Reset to default 11

By using pbkdf2-sha256 (from your own link) I'm able to generate a hash that is identical to the one you have from Django.

var pbkdf2 = require('pbkdf2-sha256');
var validatePassword = function (key, string) {
    var parts = string.split('$');
    var iterations = parts[1];
    var salt = parts[2];
    return pbkdf2(key, new Buffer(salt), iterations, 32).toString('base64') === parts[3];
};
var djangoPass = 'pbkdf2_sha256$10000$NmzpPCQiTe2R$U8ipSsOy3Xz7FwWDHdH/dTei8Xh4Q7NGtdzrCacSfvo=';
console.log(validatePassword('Simple123', djangoPass)); // Logs: true

The above code should be sufficient to validate passwords stored in Django using Node.

I recently created a project to make this easier. My project is available for node and is called node-django-hashers. The code is below:

https://github.com/kalvish21/hashers

A sample usage:

var hashers = require('node-django-hashers');

var h = new hashers.PBKDF2PasswordHasher();
var hash1 = h.encode("password", h.salt());
console.log(h.verify("password", hash1)); // returns true
console.log(h.verify("wrong_password", hash1)); // returns false

This is compatible with django password hashing.

I faced a similar task where I have to authenticate users against Django passwords in Java. After trying unsuccessfully to achieve this goal using the default pbkdf2_sha256 hasher in Django, I ended up changing the method used to hash the Django password to be able to easily replicate the same algorithm in Java.

As described in Django documentation you can modify the order in which PASSWORD_HASHERS are defined in settings.py, I put this hasher in first position:

'django.contrib.auth.hashers.SHA1PasswordHasher'

In this way the password hash stored in the Django database is something like this:

sha1$upSZarr0w7CZ$304b22b1a9e7e5387e79f50e691043d3faf83c48

If you already have some passwords in the database they will be automatically converted by Django at first user login.

You can easily tokenize the hash using $ as separator; the first token is always sha1 (the algorithm used), the second token is the salt and the last token is the actual hash.

To match a password you can verify that

304b22b1a9e7e5387e79f50e691043d3faf83c48

is the SHA1 sum of the salt concatenated with the expected password:

SHA1(upSZarr0w7CZ + password) = 304b22b1a9e7e5387e79f50e691043d3faf83c48

In our case the security implications of using a weaker algorithm for password hashing was acceptable.

pbkdf2-sha256(https://github.com/cryptocoinjs/pbkdf2-sha256) is deprecated. We should use pbkdf2 (https://www.npmjs.com/package/pbkdf2)

var pbkdf2 = require("pbkdf2");

const password = "12345678";
const djangoPassword =
  "pbkdf2_sha256$120000$uUjHWJsRsQj4$d9eBwNfRW/AayPOSMjqYyT26Sm6bsC5GCK9ntDxB8jM=";

var validatePassword = function(key, string) {
  var parts = string.split("$");
  var iterations = parts[1];
  var salt = parts[2];
  const hashPassword = pbkdf2
    .pbkdf2Sync(key, Buffer.from(salt), Number(iterations), 32, "sha256")
    .toString("base64");
  return hashPassword === parts[3];
};

console.log(validatePassword(password, djangoPassword)); // it should be print "true"
发布评论

评论列表(0)

  1. 暂无评论