【问题标题】:Django pbkdf2_sha256 JS implementationDjango pbkdf2_sha256 JS 实现
【发布时间】:2013-07-06 20:12:27
【问题描述】:

我有一个来自 django 的数据库,我想通过 Node.js 使用它。我有一个任务:验证用户。从数据库已知:算法 pbkdf2_sha256、盐、10000 次迭代和 base64 编码的哈希。我必须在 JS 中执行哪些步骤才能将一些密码编码为给定的 base64-hash?

UPD:在此处找到解决方案:python (django) hashlib vs Nodejs crypto 但 Django 生成的哈希和 JS 生成的哈希不匹配...
Django 生成下一个:

pbkdf2_sha256$10000$NmzpPCQiTe2R$U8ipSsOy3Xz7FwWDHdH/dTei8Xh4Q7NGtdzrCacSfvo=

JS:

pbkdf2_sha256$10000$NmzpPCQiTe2R$w4jCgWjDilrDmcOBd8K+I8OdwpkKwoVQZMKWH3FvYcKoAMKcwqlewobDocOEGMKZfQ==

密码:Simple123

【问题讨论】:

  • 您是否尝试从 PBKDF 获取相同数量的字节?如果您没有指定该数字,则返回 49 个字节有点奇怪。还要确保在两个函数中使用相同的密码字符编码 - 未指定 PBKDF2 的字符编码(尽管提示使用 UTF-8)。

标签: javascript django-authentication sha256 pbkdf2


【解决方案1】:

通过使用pbkdf2-sha256(来自您自己的链接),我能够生成与您从 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

以上代码应该足以使用 Node 验证存储在 Django 中的密码。

【讨论】:

【解决方案2】:

我最近创建了一个项目来简化此操作。我的项目可用于节点,名为node-django-hashers。代码如下:

https://github.com/kalvish21/hashers

示例用法:

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

这与 django 密码哈希兼容。

【讨论】:

    【解决方案3】:

    我遇到了类似的任务,我必须根据 Java 中的 Django 密码对用户进行身份验证。在尝试使用 Django 中的默认 pbkdf2_sha256 散列器未成功实现此目标后,我最终更改了用于散列 Django 密码的方法,以便能够轻松地在 Java 中复制相同的算法。

    如Django documentation 中所述,您可以修改在settings.py 中定义PASSWORD_HASHERS 的顺序,我将这个哈希器放在首位:

    'django.contrib.auth.hashers.SHA1PasswordHasher'

    这样存储在 Django 数据库中的密码哈希是这样的:

    sha1$upSZarr0w7CZ$304b22b1a9e7e5387e79f50e691043d3faf83c48

    如果您在数据库中已经有一些密码,它们将在用户首次登录时由 Django 自动转换。

    您可以使用 $ 作为分隔符轻松标记哈希;第一个标记始终是 sha1(使用的算法),第二个标记是 salt,最后一个标记是实际的 hash。

    要匹配密码,您可以验证

    304b22b1a9e7e5387e79f50e691043d3faf83c48

    是 salt 与预期密码的 SHA1 总和:

    SHA1(upSZarr0w7CZ + password) = 304b22b1a9e7e5387e79f50e691043d3faf83c48

    在我们的案例中,使用较弱的密码散列算法的安全隐患是可以接受的。

    【讨论】:

    【解决方案4】:

    pbkdf2-sha256(https://github.com/cryptocoinjs/pbkdf2-sha256) 已弃用。我们应该使用 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"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-07
      • 2018-02-14
      • 2021-03-14
      • 2022-11-18
      • 2021-01-14
      • 2013-04-16
      • 2020-12-01
      • 2021-11-17
      相关资源
      最近更新 更多