尝试在Perl中复制c#散列(在Linux上)

本文关键字:Linux 散列 复制 Perl | 更新日期: 2023-09-27 18:08:42

我没有得到相同的值(使用已知的密码)。

我怀疑这可能与编码有关,但到目前为止,我尝试过的所有方法都不起作用:

windows code (c#?):
private static string EncodePassword(string password, string salt)
{
    string encodedPassword = password;
    HMACSHA1 hash = new HMACSHA1 { Key = Convert.FromBase64String(salt) };
    encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
    return encodedPassword;
}

perl代码在linux上运行:

use Modern::Perl '2015';
use Digest::SHA qw(hmac_sha1 hmac_sha1_base64);
use MIME::Base64 qw(decode_base64 encode_base64);
use Unicode::String qw(utf16be utf16le);
say encode_base64(hmac_sha1($password, decode_base64($salt)));
# (or, equivalently)
say hmac_sha1_base64($password, decode_base64($salt));
my $le16 = utf16le($password);
my $be16 = utf16be($password);
say "ok, try utf-16 (le, then be)...";
say encode_base64(hmac_sha1($le16, decode_base64($salt)));
say encode_base64(hmac_sha1($be16, decode_base64($salt)));
# try reversing the hmac output?                                                                                                                                          
my $hmac_bytes = hmac_sha1($password, decode_base64($salt));
my $rev_bytes = reverse $hmac_bytes;
say encode_base64($rev_bytes);

尝试在Perl中复制c#散列(在Linux上)

在原始的c#代码中,在这一行:

encodedPassword = Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));

Encoding.Unicode.GetBytes的调用通过UTF-16LE编码器将密码转换为字节数组。

您必须执行相同的转换才能在Perl中获得相同的哈希值:

use Digest::SHA qw(hmac_sha1);
use MIME::Base64 qw(decode_base64 encode_base64);
use Encode qw(encode);
$utf16LEPassword = encode("UTF-16LE", $password);
print encode_base64(hmac_sha1($utf16LEPassword, decode_base64($salt)));