使用 Perls unpack() 验证加盐哈希

Posted

技术标签:

【中文标题】使用 Perls unpack() 验证加盐哈希【英文标题】:Verifying salted hashes with Perls unpack() 【发布时间】:2010-12-18 12:19:07 【问题描述】:

我正在尝试使用 Perl 验证加盐密码,但无法解压。

我有一个加盐哈希密码,例如对于 SHA256:SSHA256 = SHA256('password' + 'salt') + 'salt' Base64 编码得到 ' SSHA256eje4XIkY6sGakInA+loqtNzj+QUo3N7sEIsj3fNge5lzYWx0'。

我将此字符串存储在我的用户数据库中。当用户登录时,需要将盐与哈希分开,以使用盐对提供的密码进行哈希处理,并将结果与​​从数据库中检索到的结果进行比较。这就是我卡住的地方。我似乎没有正确的解包模板将哈希(8 位二进制,固定长度,在本例中为 32 字节)与盐(8 位二进制,可变长度)分开。

我尝试过类似my ($hash, $salt) = unpack('N32 N*', $data); 但这似乎行不通。

我的问题是:我怎样才能解压这个哈希(在它被 Base64 解码之后)以得到一个固定长度的哈希和另一个变量的可变长度盐?

【问题讨论】:

【参考方案1】:

我认为你是在不必要地重新发明***。

你可以使用例如Crypt::SaltedHash 方便验证,例如:

我的 $password_entered = $cgi->param('password'); 我的 $valid = Crypt::SaltedHash->validate($salted, $password_entered);

一个更长的例子,展示了在第一个实例中使用 Crypt::SaltedHash 来生成加盐密码:

我的 $csh = Crypt::SaltedHash->new(algorithm => 'SHA-256'); $csh->add('secretpassword'); 我的 $salted = $csh->generate; # $salted 将包含加盐哈希(Crypt::SaltedHash 随机选择 # 自动为你加盐) # 例如: DB x $salted = $csh->generate; 0 'SSHA256H1WaxHcyAB81iyIPwib/cCUtjqCm2sxQNA1QvGeh/iT3m51w' # 验证明文'secretpassword'表明它是正确的: DB x Crypt::SaltedHash->validate($salted, 'secretpassword'); 0 1 # 并尝试使用错误的密码: DB x Crypt::SaltedHash->validate($salted, 'wrongpassword'); 0''

没有理由自己重新发明所有这些。

【讨论】:

这个模块没有做我需要做的事情,但总的来说它可能值得再看一下。 它不能帮助您将盐与盐分哈希密码分开,不,但正如我所说,我认为您最好让 Crypt::SaltedHash 负责比较哈希密码你。它已经过试验和测试,人们重新发明与安全相关的代码总是让我感到紧张 :) 然而,TIMTOWDI 一如既往!【参考方案2】:

您似乎在艰难地执行 RFC2307,并且还设法引入了错误。那些+ 并不代表你的想法。

改为子类Authen::Passphrase::SaltedDigest。

【讨论】:

【参考方案3】:

不确定整个图片是否存在,但您指定的 unpack 模板 -'N32 N*'- 适用于 32 个 unsigned long(32 位)(大端)整数(@ 987654321@).

看起来您可能需要无符号字符:'32C C*'

【讨论】:

谢谢,最终这导致了我的解决方案。

以上是关于使用 Perls unpack() 验证加盐哈希的主要内容,如果未能解决你的问题,请参考以下文章

一个简单的方式搞定密码的加盐哈希与验证

加盐密码哈希:如何正确使用

如何在 c# 中验证 windows 应用程序的加盐密码和用户名?

加盐密码哈希:如何正确使用

将用户密码从加盐 SHA1 升级到 bcrypt

用户名、密码、加盐、加密、哈希 - 这一切是如何工作的? [复制]