如何使 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!
的新手
我有一个 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!
的新手