1

我得到了 C# 代码,我正在尝试使用 Perl 生成等效的 SHA1。

public string GetHashedPassword(string passkey)
{
       // Add a timestamp to the passkey and encrypt it using SHA1.
       string passkey = passkey + DateTime.UtcNow.ToString("yyyyMMddHH0000");
       using (SHA1 sha1 = new SHA1CryptoServiceProvider())
       {
              byte[] hashedPasskey =
                     sha1.ComputeHash(Encoding.UTF8.GetBytes(passkey));
              return ConvertToHex(hashedPasskey);
       }
}
private string ConvertToHex(byte[] bytes)
{
       StringBuilder hex = new StringBuilder();
       foreach (byte b in bytes)
       {
              if (b < 16)
              {
                     hex.AppendFormat("0{0:X}", b);
              }
              else
              {
                     hex.AppendFormat("{0:X}", b);
              }
       }
       return hex.ToString();
}

与以下相同:

use Digest::SHA1 qw( sha1_hex );
my $pass = "blahblah";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime();
$year += 1900;
my $date = sprintf("%d%02d%02d%02d0000", $year, $mon+1, $mday, $hour);    
my $passSha1 = sha1_hex($pass.$date);
//9c55409372610f8fb3695d1c7c2e6945164a2578

我实际上没有任何 C# 经验,因此我无法测试 C# 代码通常输出的内容。

该代码应该用作网站的校验和,但我提供的代码失败了。

编辑:它还在散列之前将UTC时间戳(yyyyMMDDHH0000)添加到通行证的末尾,因此我添加了该代码以防出现问题。

4

5 回答 5

5

我也不懂 C#。但是,{0:X}使用大写字母格式化十六进制数字。那么,会

my $passSha1 = uc sha1_hex($pass);

帮助?(假设GetHashedPassword是有道理的。)

于 2009-08-05T04:49:56.413 回答
4

我可以看到的唯一区别(在 Visual Studio 2008 下运行代码)是 C# 代码返回带有大写字母的十六进制字符串

D3395867D05CC4C27F013D6E6F48D644E96D8241

并且 perl 代码使用小写字母表示

d3395867d05cc4c27f013d6e6f48d644e96d8241

C# 代码中使用的格式字符串要求大写(“X”而不是“x”):

hex.AppendFormat("{0:X}", b);

也许网站上的代码使用区分大小写的比较?我认为在提交之前将 CPAN 函数的输出转换为大写对您来说是微不足道的吗?

于 2009-08-05T04:50:35.930 回答
2

是否可以像将调用中的大写“ X”更改为小写“”一样简单?AppendFormatx

于 2009-08-05T04:51:44.290 回答
0

我想你正在寻找Digest::SHA1

于 2009-08-05T04:30:13.630 回答
0

您的 SHA-1 也可能是:

BitConverter.ToString(SHA.ComputeHash(buffer)).Replace("-", "");
于 2012-01-29T18:10:13.873 回答