使用Perls unpack()验证盐渍哈希值

时间:2010-12-18 12:19:07

标签: perl hash passwords unpack

我正在尝试使用Perl验证salted密码,并且解压缩了。

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

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

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

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

3 个答案:

答案 0 :(得分:4)

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

您可以使用例如Crypt::SaltedHash可以轻松验证它,例如:

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

更长的例子,显示使用Crypt :: SaltedHash在第一个实例中生成盐渍密码:

my $csh = Crypt::SaltedHash->new(algorithm => 'SHA-256');
$csh->add('secretpassword');
my $salted =  $csh->generate;
# $salted will contain the salted hash (Crypt::SaltedHash picks random
# salt for you automatically)

# for example:
  DB x $salted = $csh->generate;
0  '{SSHA256}H1WaxHcyAB81iyIPwib/cCUtjqCm2sxQNA1QvGeh/iT3m51w'

# validating that against the plaintext 'secretpassword' shows it's right:
  DB x Crypt::SaltedHash->validate($salted, 'secretpassword');
0  1

# and trying it with an incorrect password:
  DB x Crypt::SaltedHash->validate($salted, 'wrongpassword');
0  ''

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

答案 1 :(得分:2)

您似乎正在以艰难的方式进行RFC2307并且还设法引入错误。那些+并不代表你的想法。

而是子类Authen::Passphrase::SaltedDigest

答案 2 :(得分:1)

不确定整个图片是否存在,但您指定的unpack模板 - 'N32 N*' - 适用于32 unsigned long (32位)(big-endian) )整数(see pack docs)。

您可能需要使用未签名的字符:'32C C*'