Search code examples
cryptographyshasha256crypto++

What's the difference between C# SHA256Managed and cryptopp::SHA256


I'm trying to replace MS SHA256Managed function by cryptopp::SHA256. Here's the C# code

internal byte[] GenerateKey(byte[] keySeed, Guid keyId)
{
        byte[] truncatedKeySeed = new byte[30];
        Array.Copy(keySeed, truncatedKeySeed, truncatedKeySeed.Length);
        Console.WriteLine("Key Seed");
        foreach (byte b in truncatedKeySeed)
        {
            Console.Write("0x" + Convert.ToString(b, 16) + ",");
        }
        Console.WriteLine();
        //
        //  Get the keyId as a byte array
        //
        byte[] keyIdAsBytes = keyId.ToByteArray();
        SHA256Managed sha_A = new SHA256Managed();
        sha_A.TransformBlock(truncatedKeySeed, 0, truncatedKeySeed.Length, truncatedKeySeed, 0);
        sha_A.TransformFinalBlock(keyIdAsBytes, 0, keyIdAsBytes.Length);

        byte[] sha_A_Output = sha_A.Hash;
        Console.WriteLine("sha_a:" + sha_A_Output.Length);
        foreach (byte b in sha_A_Output)
        {
            Console.Write("0x" + Convert.ToString(b, 16) + ",");
        }
        Console.WriteLine(); 
        .....
}

The output result:

Key Seed 0x5d,0x50,0x68,0xbe,0xc9,0xb3,0x84,0xff,0x60,0x44,0x86,0x71,0x59,0xf1,0x6d,0x6b,0x75,0x55,0x44,0xfc,0xd5,0x11,0x69,0x89,0xb1,0xac,0xc4,0x27,0x8e,0x88

Key ID 0x39,0x68,0xe1,0xb6,0xbd,0xee,0xf6,0x4f,0xab,0x76,0x8d,0x48,0x2d,0x8d,0x2b,0x6a,

sha_a:32 0x7b,0xec,0x8f,0x1b,0x60,0x4e,0xb4,0xab,0x3b,0xb,0xbd,0xb8,0x71,0xd6,0xba,0x71,0xb1,0x26,0x41,0x7d,0x99,0x55,0xdc,0x8e,0x64,0x76,0x15,0x23,0x1b,0xab,0x76,0x62,

The replacement function by Crypto++ as follows:

  byte key_seed[] = { 0x5D, 0x50, 0x68, 0xBE, 0xC9, 0xB3, 0x84, 0xFF, 0x60, 0x44, 0x86, 0x71, 0x59, 0xF1, 0x6D, 0x6B, 0x75, 0x55, 0x44, 0xFC,0xD5, 0x11, 0x69, 0x89, 0xB1, 0xAC, 0xC4, 0x27, 0x8E, 0x88 };
  byte key_id[] = { 0x39,0x68,0xe1,0xb6,0xbd,0xee,0xf6,0x4f,0xab,0x76,0x8d,0x48,0x2d,0x8d,0x2b,0x6a };
  byte truncated_key_seed[sizeof(key_seed)];
  memset( truncated_key_seed,0,sizeof(truncated_key_seed));
  memcpy( key_seed, truncated_key_seed, sizeof(key_seed) );
  byte output[SHA256::DIGESTSIZE];
  memset(output,0,sizeof(output));

  SHA256 sha_a;
  sha_a.Update(truncated_key_seed,sizeof(key_seed));
  sha_a.Update(key_id,sizeof(key_id));
  sha_a.Final(output);
  printf("size:%lu\n",sizeof(output));
  PrintHex(output,sizeof(output));

But the output hash value is DB 36 C9 F6 F7 29 6D 6F 52 21 DA 9F 55 1D AE BC 3E 5A 15 DF E1 37 07 EE 8F BC 73 61 5F D6 E1 C3 It's different with sha_a result by C#.

From the MSDN and Cryptopp reference, the SHA256Managed::TransformBlock and SHA256Managed::TransformFinalBlock did the same thing with Cryptopp::Update and Cryptopp::Final.

What's the difference between SHA256Managed and cryptopp::SHA256 cause this result?


Solution

  • Seems like a bug in your code to me.

      sha_a.Update(truncated_key_seed,sizeof(key_seed));
    

    Make sure that the truncated_key_seed is identical in both versions, especially the bytes not included in the original key_seed...