如何在我的flutter应用程序中准确生成由python编码的哈希密码



我的数据库中存储了一个由python api生成的哈希密码。散列密码是使用参数为hmac sha256的hashlib.pbkdf2_hmac包生成的,短语编码为utf8字节,salt也以字节为单位,迭代次数为100000,派生密钥长度为64。派生的密钥然后与salt连接,并编码为十六进制字符串,然后成为用户的哈希密码。我需要散列密码作为fernet密钥的基础,该密钥用于加密将发送到我的flutter应用程序的文件。现在,我没有将散列密码和请求一起发送到flutter应用程序,而是尝试在我的flutter应用中复制这个过程。我发现了这个名为steel_crypt PassCrypt.pbkdf2().hash()函数的flutter包,它具有pbkdf2哈希算法,该算法还需要salt、短语、hmac sha256、派生密钥长度和迭代。短语可以由个人用户提供,因为它是他/她的密码。salt可以通过从数据库中分离散列密码来获取。我会在请求中向应用程序发送盐,因为我认为它相当安全,因为它只是盐。我现在试图复制这个过程,但不知何故,它们永远不会匹配。我认为这与传递给参数的参数的编码有关。有人使用过pythonhashlib.pbkdf2_hmac函数吗?我已经深入研究了该算法,试图找出每个参数的运行时类型,或者它们是否重要。我已经了解了有关ascii字符串、utf8编码、符文、列表、原始字符串和十六进制字符串的信息。这变得令人沮丧。我甚至不知道python的b‘byte’符号是否也是一个因素。Uint8List不就是一个List<int>吗?

这是我的python api片段

def pbkdf2_encode(phrase, slen=16, dklen=64):
try:
salt = os.urandom(slen)  
encoded_key = hashlib.pbkdf2_hmac(
'sha256',
phrase.encode('utf-8'),
salt,
100000,
dklen = dklen,
) 
return (salt + encoded_key).hex()
except Exception:
traceback.print_exc()
raise Exception

这是我的颤振代码片段

var _hexSalt = '69b4c653613f0e5e2198425dbae704bf'; //<-- received from request
var _byteSalt = hex.decode(_hexSalt);
int _iterations = 100000;
var _passHashByte = PassCryptRaw.pbkdf2(iterations: _iterations, hmac: HmacHash.Sha_256);
var derived_key = _passHashByte.hash(salt: _byteSalt, len: 64, plain: utf8.encode('admin')); //<-- 'admin' is the phrase
var _hexHashedPassword = "69b4c653613f0e5e2198425dbae704bf4b42f01a65f706dd26"
"64ffc9c08e1b84f7899300a2b19082b8e6ebd9579e759b7a249ee03a9033544f4576f24"
"8f82bfc5d6ef0a36c4c3122b2dd5d4530c4e598"; //<-- just for reference
var _hexHashedPasswordWithoutSalt = "4bf4b42f01a65f706dd26"
"64ffc9c08e1b84f7899300a2b19082b8e6ebd9579e759b7a249ee03a9033544f4576f24"
"8f82bfc5d6ef0a36c4c3122b2dd5d4530c4e598"; //<-- just for reference

print(hex.encode(derived_key));
print(_hexHashedPasswordWithoutSalt);

// hex.encode(derived_key) should be equal to _hexHashedPasswordWithoutSalt

我开始怀疑这是否是正确的方法。我必须指出,flutter函数中的salt和短语期望使用Uint8List。我怀疑是这些部分把我搞砸了。有人能指出我做错了什么吗?或者,如果你能指出如何实现我的要求?

我正在测试其他包,并安装了这些名为pbkdf2_dartpassword_hash的包,当时我并不知道,但这些包具有相同的类名和构造函数PBKDF2。到这个时候,我已经放弃了steel_crypt。我第一次尝试测试password_hash,它的文档说,如果没有定义,默认的哈希算法是Sha256。这一切对我来说都很好,因为我使用的是Sha256,所以我没有在构造函数中定义我的哈希算法。你知道吗,当你调用类时,即使没有导入包,flutter也会自动导入你想要使用的包?现在,我没有读取与我导入的PBKDF2类对应的包名称,但后来我发现我导入的是pdkdf2_dart包,其默认哈希算法是Sha1。苏。。。当然,生成的密钥与我的哈希密码不匹配。然后,我使用pbkdf2_dart更新了我的代码,并在不知不觉中再次认为默认算法是Sha256。再一次,他们不匹配。然后我决定调用这两个函数来并排比较它们,然后我发现它们的类名是相同的,这迫使我给它们取别名。同时,这让我想,我是不是只是在测试时切换了它们?然后我看了一下我的浏览器,它的当前页面是pbkdf2_dart构造函数页面。我是怎么发现我一直使用的哈希算法不是正确的呢。最终,pbkdf2_dart在纠正了散列算法错误之后生成了正确的散列密钥。

经验教训:在编码时,请小心确保导入了正确的包,因为可能还有其他包的类名和方法名相似或更糟,但完全相同。

最新更新