如何使 SJCL 和 Python hashlib 生成相同的 pdkdf2 输出

How to make SJCL and Python hashlib generate identical pdkdf2 output

我有一个 JavaScript 应用程序和一个 Python 应用程序,它们使用从使用 pbdkf2 的密码派生的密钥进行通信。问题是,生成的密钥不匹配。我为每一个都制作了一个最小的测试用例。

Python

import hashlib, binascii
bytes = hashlib.pbkdf2_hmac('sha256', "password".encode(), b'', 100000)
print(binascii.hexlify(bytes).decode())

生成:64a868d4b23af696d3734d0b814d04cdd1ac280128e97653a05f32b49c13a29a

JavaScript

<script src="lib/sjcl.js"></script>
<script>
var hmacSHA256 = function (key) {
    var hasher = new sjcl.misc.hmac(key, sjcl.hash.sha256);
    this.encrypt = function () {
        return hasher.encrypt.apply(hasher, arguments);
    };
};
hash = sjcl.misc.pbkdf2("password", [0], 100000, 256, hmacSHA256);
console.log(sjcl.codec.hex.fromBits(hash));
</script>

生成:41c04f824d843d5be0ae66b3f621d3f05db7d47e7c46ee0e9171b5cbff7f3631

我现在很头疼。我认为 b''[0] 是等效的盐,但我不确定。我认为他们都使用 utf-8 对密码进行编码,但我不确定。而且我不相信 JavaScript hmacSHA256 函数与 Python 正在做的完全匹配。或者它可能仍然是其他东西。

在我的脑海里,你检查过了吗

hash = sjcl.misc.pbkdf2("password", "", 100000, 256);

给出正确的结果?

据我所知 docs,SJCL 的 PBKDF2 实现默认为 HMAC-SHA256,如果你没有明确地给它一个 PRF。如果进行更改修复了错误,那么您的 hmacSHA256 包装器可能有问题。

此外,我不确定将空盐指定为 [0] 是否真的有效(或者保证在未来版本中有效,因为 SJCL 的 bitArrays 的格式是 explicitly subject to change),但是 "" 绝对应该有效。

这是根据我最近的经验分享给大家的。

我的objective:

使用Python生成PBKDF2密码。客户端将是 Android (Java),后端将是 Flask (Python).

问题:

在测试时,我发现两个版本(Java vs Python)产生了不同的散列输出(所有其他参数都相同 - SHA256、1000 次迭代,类似 SALT)

我发现了什么: 使用互联网上可用的 PBKDF2 生成工具,Android 结果是完全匹配的,而 Python 则不是。所以很有可能 Python 结果在某种程度上是有偏差的.....

问题已解决:

在 SO 中寻找可能的解释时,我发现我在 Python 中将字符串转换为字节的方式在某种程度上并不完全正确:

原代码:

dk = hashlib.pbkdf2_hmac('sha256', b'base64_message', b'salt', 1000)

工作代码:

dk = hashlib.pbkdf2_hmac('sha256', base64_message.encode(), salt.encode(), 1000)

这可能是因为我缺乏Python的经验。希望这篇笔记对其他人有用,尤其是 Python!

的新手