2

我正在尝试使用 Perl 验证加盐密码,但我被 unpack 卡住了。

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

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

我尝试过类似
my ($hash, $salt) = unpack('N32 N*', $data);
的方法,但似乎没有成功。

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

4

3 回答 3

4

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

您可以使用例如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 '{SSHA256}H1WaxHcyAB81iyIPwib/cCUtjqCm2sxQNA1QvGeh/iT3m51w'

# 验证明文'secretpassword'表明它是正确的:
  DB x Crypt::SaltedHash->validate($salted, 'secretpassword');
0 1

# 并尝试使用错误的密码:
  DB x Crypt::SaltedHash->validate($salted, 'wrongpassword');
0''

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

于 2010-12-18T21:22:07.017 回答
2

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

子类Authen::Passphrase::SaltedDigest代替。

于 2010-12-18T16:06:07.750 回答
1

不确定整个图片是否存在,但unpack您指定的模板 - 'N32 N*'- 适用于 32 个无符号长(32 位)(大端)整数(请参阅 pack docs)。

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

于 2010-12-18T13:11:21.770 回答