2017-10-19 53 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);