tags:

views:

354

answers:

4

I was given C# code and I'm trying to generate the equivalent SHA1 using Perl.

public string GetHashedPassword(string passkey)
{
       // Add a timstamp 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();
}

The same as:

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

I don't actually have any C# experience so I'm not able to test what is normally outputted from the C# code.

The code is supposed to be used as a checksum for a website but the one I'm providing is failing.

Edit: it also adds the UTC timestamp (yyyyMMDDHH0000) to the end of the pass before hashing so I've added that code incase its something there.

A: 

I think you're looking for Digest::SHA1

stran
No, he knows about `Digest::SHA1`. He wants to verify if the C# code he has will produce the same output as the `sha1_hex` method.
Sinan Ünür
My reading of the question is that the asker has the C# code and wants equivalent Perl code, in which case using the CPAN module is a much better idea that writing new code (with some exceptions - learning about stuff being one reason to rewrite it)
Cebjyre
Thanks Sinan I edited my question to make it clear that I'm using Digest.
rezzif
I've already provided the code that uses the cpan module!
rezzif
+4  A: 

I do not know C# either. However, {0:X} formats hex digits using upper case letters. So, would

my $passSha1 = uc sha1_hex($pass);

help? (Assuming GetHashedPassword makes sense.)

Sinan Ünür
Thats it thanks.
rezzif
+4  A: 

The only difference I can see (from running the code under Visual Studio 2008) is that the C# code is returning the hex string with alphas in uppercase

D3395867D05CC4C27F013D6E6F48D644E96D8241

and the perl code is using lower case for alphas

d3395867d05cc4c27f013d6e6f48d644e96d8241

The format string used in the C# code is asking for uppercase ("X" as opposed to "x"):

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

Maybe the code at the website is using a case sensitive comparison? I assume it would be trivial for you to convert the output from the CPAN function to uppercase before you submit it?

Hamish Smith
+2  A: 

Could it be as simple as changing the uppercase 'X' in the AppendFormat call to a lowercase 'x'?

Matt Bridges