2017-10-19 55 views
2

我想學習.NET API,並創建了一個程序,它將源文件中的密鑰與XML文件中的密鑰進行比較。不成功的驗證(C#.NET HMACSHA256類)

我用下面的exaple(用於varifying文檔第三種方法:

https://docs.microsoft.com/en-gb/dotnet/api/system.security.cryptography.hmacsha256?view=netframework-4.7.1

現在我的程序運行,但它總是說文件已被篡改,即使我絕對相信,他們不是因爲我剛剛創建了他們

這裏是我的代碼:

VerifyDocument.cs

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Xml.Serialization; 

public class VerifyDocument 
{ 

public static void Main(string[] args) 
{ 

XmlSerializer xml = new XmlSerializer(typeof(byte[])); 
byte[] key; 
string keyFile = args[1]; 
string sourceFile = args[0]; 
using (StreamReader reader = new StreamReader(keyFile)) { 
    key = (byte[]) xml.Deserialize(reader); 
} 

bool err = false; 

     using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object. 
     { 

      byte[] storedHash = new byte[hmac.HashSize/8]; // Create an array to hold the keyed hash value read from the file. 

      using (FileStream inStream = new FileStream(sourceFile, FileMode.Open)) // Create a FileStream for the source file. 
      { 

       inStream.Read(storedHash, 0, storedHash.Length); // Read in the storedHash. 

       byte[] computedHash = hmac.ComputeHash(inStream); 
       // compare the computed hash with the stored value 

       for (int i = 0; i < storedHash.Length; i++) 
       { 
        if (computedHash[i] != storedHash[i]) 
        { 
         err = true; 
        } 
       } 
      } 
     } 
     if (err) 
     { 
      Console.WriteLine("Hash values differ! Signed file has been tampered with!"); 

     } 
     else 
     { 
      Console.WriteLine("Hash values agree -- no tampering occurred."); 

     } 

} 

} 

SignDocument.cs

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Xml.Serialization; 

public class HMACSHA256example 
{  

    public static void Main(string[] args) 
    { 


    if (args.Length != 2) { 
     Console.WriteLine("Usage: [mono] SignDocument.exe <filename> <key>"); 
     Environment.Exit(1); 
    } else 
    { 
     XmlSerializer xml = new XmlSerializer(typeof(byte[])); 
     byte[] key; 
     string keyFile = args[1]; 
     string sourceFile = args[0]; 
     string destFile = sourceFile + ".hash"; 
     using (StreamReader reader = new StreamReader(keyFile)) { 
     key = (byte[]) xml.Deserialize(reader); 
     } 

     using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object. 
     { 
      using (FileStream inStream = new FileStream(sourceFile, FileMode.Open)) 
      { 
       using (FileStream outStream = new FileStream(destFile, FileMode.Create)) 
       { 

        byte[] hashValue = hmac.ComputeHash(inStream); // Compute the hash of the input file. 


        outStream.Write(hashValue, 0, hashValue.Length); // Write the computed hash value to the output file. 

      } 
     } 

    } 

} 
} 
} 

CreateKey.cs

using System; 
using System.IO; 
using System.Security.Cryptography; 
using System.Xml.Serialization; 

namespace COMP3911.Crypto { 


class CreateKey { 
static void Main(string[] args) { 

    string input; 

    if (args.Length == 0) { 
    Console.WriteLine("Usage: [mono] CreateKey.exe <filename>"); 
    Environment.Exit(1); 
    } 

    byte[] secretkey = new Byte[64]; 
     //RNGCryptoServiceProvider is an implementation of a random number generator. 
     using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
     { 
      // The array is now filled with cryptographically strong random bytes. 
      rng.GetBytes(secretkey); 
     } 


    // XML 
    string keyfile = args[0] + ".key"; 
    using (StreamWriter output = new StreamWriter(keyfile, false)) { 
    XmlSerializer xml = new XmlSerializer(typeof(byte[])); 
    xml.Serialize(output, secretkey); 
    } 
} 
} 

} 

任何幫助將不勝感激!

+0

「我做錯了什麼?」這不是一個真正的問題。請閱讀[問]並編輯您的問題以獲得正確的標題 –

+0

您需要分享您如何創建您正在檢查的文件。您共享的代碼看起來很合理,假設您正在檢查的文件的格式與代碼期望的一樣(文件的開頭是文件其餘部分的HMAC-SHA256)。 – smarx

+0

嗨smarx。我剛剛分享了我正在使用的3個小程序,其中包括生成XML密鑰併爲指定文件的內容計算HMAC的程序。 –

回答

0

您的「簽名」程序讀取inStream並將HMAC寫入outStream

您的「驗證」程序讀取一個文件,並期望它是HMAC後跟數據。

要麼「符號」倒帶inStream,然後將其複製到outStream或您需要更改「驗證」以獨立查看這兩個文件。

0

SignDocument.cs有錯誤。您正在編寫簽名,但未能寫入文件的其餘部分。

應該是這樣的(大多是從文檔頁面複製鏈接到您):

using (HMACSHA256 hmac = new HMACSHA256(key)) // Initialize the keyed hash object. 
{ 
    using (FileStream inStream = new FileStream(sourceFile, FileMode.Open)) 
    { 
     using (FileStream outStream = new FileStream(destFile, FileMode.Create)) 
     { 
      byte[] hashValue = hmac.ComputeHash(inStream); // Compute the hash of the input file. 
      outStream.Write(hashValue, 0, hashValue.Length); // Write the computed hash value to the output file. 

      inStream.Position = 0; 
      int bytesRead; 
      byte[] buffer = new byte[1024]; 
      do 
      { 
       bytesRead = inStream.Read(buffer, 0, 1024); 
       outStream.Write(buffer, 0, bytesRead); 
      } while (bytesRead > 0); 

     } 
    } 
} 

UPDATE

不知道爲什麼MSDN版本不使用CopyTo,但似乎更好:

byte[] hashValue = hmac.ComputeHash(inStream); 
outStream.Write(hashValue, 0, hashValue.Length); 

inStream.Position = 0; 
inStream.CopyTo(outStream);