首先,您现有的代码存在严重的安全漏洞。盐不应该是恒定的。应为每个密码使用不同的随机盐。
use Math::Random::Secure::RNG qw( ); # Or some other cryptographic-safe number generator
use feature qw( state );
sub generate_salt {
state $rng = Math::Random::Secure::RNG->new();
my $uint32 = $rng->irand();
return pack('N', $uint32);
}
sub hash_password {
my ($password, $salt) = @_;
return sha1($password . $salt);
}
sub encode_password {
my ($plaintext_password) = @_;
my $salt = generate_salt();
my $hashed_password = hash_password($plaintext_password, $salt);
return join('-',
encode_base64($salt, ''),
encode_base64($hashed_password, ''),
);
}
sub is_correct_password {
my ($plaintext_password, $encoded_password) = @_;
my ($salt_base64, $hashed_password_base64) = split(/-/, $encoded_password);
my $salt = decode_base64($salt_base64);
my $hashed_password = decode_base64($hashed_password_base64);
return hash_password($plaintext_password, $salt) eq $hashed_password;
}
修改密码:
my $plaintext_password = '...from user...';
my $encoded_password = encode_password($plaintext_password);
检查密码:
my $plaintext_password = '...from user...';
my $encoded_password = '...from storage...';
if (!is_correct_password($plaintext_password, $encoded_password)) {
die("Authentication error\n");
}
不过,这仍然是错误的。 sha1 太弱了。应该使用至少 10,000 次迭代的 PBKDF2。