2017-10-19 6 views
2

Ich versuche, die .NET-API zu lernen, und ich erstellte ein Programm, das den Schlüssel in der Quelldatei mit einem Schlüssel aus einer XML-Datei vergleicht.Erfolglose Überprüfung (C# .NET HMACSHA256-Klasse)

ich verwendet, um die folgenden exaple (die dritte Methode für Verifizieren von allen ein Dokument:

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

jetzt rechts mein Programm läuft, aber es sagt immer, dass die Dateien mit noch manipuliert wurden, obwohl ich bin absolut sicher, dass sie sind nicht da ich gerade sie erstellt

Hier ist mein Code:.

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); 
    } 
} 
} 

} 

Jede Hilfe wäre sehr dankbar!

+0

"Was mache ich falsch?" Ist keine echte Frage. Bitte lesen Sie [ask] und bearbeiten Sie Ihre Frage, um einen korrekten Titel zu erhalten. –

+0

Sie müssen angeben, wie Sie die zu überprüfende Datei erstellt haben. Der Code, den Sie freigegeben haben, sieht vernünftig aus, vorausgesetzt, die zu überprüfende Datei ist so formatiert, wie der Code es erwartet (der Anfang der Datei ist ein HMAC-SHA256 des Rests der Datei). – smarx

+0

Hallo Smarx. Ich habe gerade die 3 kleinen Programme geteilt, die ich benutze, einschließlich die, die einen XML-Schlüssel erzeugt und HMAC für den Inhalt einer spezifizierten Datei berechnet. –

Antwort

0

Ihr "Zeichen" Programm liest inStream und schreibt nur den HMAC zu outStream.

Ihr Programm "verify" liest eine Datei und erwartet, dass es der HMAC gefolgt von den Daten ist.

Entweder "Zeichen" muss inStream zurückspulen und dann kopieren Sie es in outStream oder Sie müssen "überprüfen" ändern, um die beiden Dateien unabhängig zu betrachten.

0

SignDocument.cs hat den Fehler. Sie schreiben die Signatur, schreiben aber den Rest der Datei nicht.

Es sollte so etwas wie dieses (meist aus der Dokumentationsseite kopiert Sie verknüpft):

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

nicht sicher, warum die MSDN-Version nicht CopyTo verwendet, sondern scheint besser:

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

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