试图在Perl中复制C#散列(在Linux上)

时间:2015-08-19 19:12:02

标签: c# perl

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

我怀疑这可能与编码有关,但到目前为止,我尝试过的所有事情都无法发挥作用:

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;
}

在linux上运行perl代码:

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);

1 个答案:

答案 0 :(得分:2)

在原始的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)));