2016-07-19 16 views
2

Ich versuche, eine Konsole-Anwendung, die Datei verschlüsseln und entschlüsseln können. Ich gab verschlüsselte Datei eine benutzerdefinierte Dateierweiterung ".aes" (z. B. probfile.aes) jetzt das Problem ist, wenn ich die Datei entschlüsseln gibt es keine Möglichkeit zu identifizieren, was ist die ursprüngliche Erweiterung der Datei, wenn es verschlüsselt wurde. Gibt es eine Chance, dass ich Dateityp von AES 256 verschlüsselte Datei bekommen kann?Wie bekomme ich Dateityp von AES 256 verschlüsselte Datei

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.IO; 
using System.Security.Cryptography; 

namespace FileEncryption 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      if (args.Length < 2) 
      { 
       Environment.ExitCode = 1; 
       Console.Error.WriteLine(Strings.CommandlineUsage); 
       return; 
      } 

      bool encrypt = args[0].StartsWith("-e", StringComparison.InvariantCultureIgnoreCase); 
      bool decrypt = args[0].StartsWith("-d", StringComparison.InvariantCultureIgnoreCase); 

      if (!(encrypt || decrypt)) 
      { 
       Environment.ExitCode = 1; 
       Console.Error.WriteLine(Strings.CommandlineUnknownMode); 
       return; 
      } 

      string inputname = (args.Length >= 3) ? args[2] : null; 

      if (inputname != null && !File.Exists(inputname)) 
      { 
       Environment.ExitCode = 2; 
       Console.Error.WriteLine(Strings.CommandlineInputFileNotFound); 
       return; 
      } 

      byte[] passwordBytes = Encoding.UTF8.GetBytes(args[1]); 
      // Hash the password with SHA256 
      passwordBytes = SHA256Managed.Create().ComputeHash(passwordBytes); 

      try 
      { 
       if (encrypt) 
       { 
        //Encrypt file     
        byte[] bytesToBeEncrypted = File.ReadAllBytes(inputname); 
        byte[] bytesEncrypted = AES_Encrypt(bytesToBeEncrypted, passwordBytes); 

        //Save encrypted file 
        string fileEncrypted = inputname.Remove(inputname.IndexOf('.')) + ".aes"; 
        File.WriteAllBytes(fileEncrypted, bytesEncrypted); 
       } 
       else 
       { 
        byte[] bytesToBeDecrypted = File.ReadAllBytes(inputname); 
        byte[] bytesDecrypted = AES_Decrypt(bytesToBeDecrypted, passwordBytes); 

        string file = inputname; 
        File.WriteAllBytes(file, bytesDecrypted); 
       } 
       Environment.ExitCode = 0; 
      } 
      catch (Exception ex) 
      { 
       Console.Error.WriteLine(string.Format(Strings.CommandlineError, ex.Message)); 
      }   
     } 


     //*********************************************************************************************** 
     // --- HELPER FUNCTIONS --- 
     //* 

     //Encrypt File 
     public static byte[] AES_Encrypt(byte[] bytesToBeEncrypted, byte[] passwordBytes) 
     { 
      byte[] encryptedBytes = null; 

      // Set your salt here, change it to meet your flavor: 
      // The salt bytes must be at least 8 bytes. 
      byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 

      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (RijndaelManaged AES = new RijndaelManaged()) 
       { 
        AES.KeySize = 256; 
        AES.BlockSize = 128; 

        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 
        AES.Key = key.GetBytes(AES.KeySize/8); 
        AES.IV = key.GetBytes(AES.BlockSize/8); 

        AES.Mode = CipherMode.CBC; 

        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length); 
         cs.Close(); 
        } 
        encryptedBytes = ms.ToArray(); 
       } 
      } 

      return encryptedBytes; 
     } 

     //Decrypt File 
     public static byte[] AES_Decrypt(byte[] bytesToBeDecrypted, byte[] passwordBytes) 
     { 
      byte[] decryptedBytes = null; 

      // Set your salt here, change it to meet your flavor: 
      // The salt bytes must be at least 8 bytes. 
      byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 

      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (RijndaelManaged AES = new RijndaelManaged()) 
       { 
        AES.KeySize = 256; 
        AES.BlockSize = 128; 

        var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000); 
        AES.Key = key.GetBytes(AES.KeySize/8); 
        AES.IV = key.GetBytes(AES.BlockSize/8); 

        AES.Mode = CipherMode.CBC; 

        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)) 
        { 
         cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length); 
         cs.Close(); 
        } 
        decryptedBytes = ms.ToArray(); 
       } 
      } 

      return decryptedBytes; 
     } 
    } 
} 

Ich weiß, dass die Art der verschlüsselten Datei nicht die ursprüngliche Erweiterung zu identifizieren ist. Was ich tun würde ist, dass wenn ich die Datei verschlüsseln werde ich es .originalextension.aes geben (z. B. picture.png.aes) und dann, wenn ich es entschlüssele, muss ich nur .aes Erweiterung entfernen. Ich frage mich nur, ob das ein guter Weg ist oder nicht?

+0

Sie würden den Dateidaten einen wohldefinierten Header voranstellen, der alle gewünschten Metadaten enthält, zum Beispiel den ursprünglichen Dateinamen, und dann alles verschlüsseln. Wenn Sie die Erweiterung nicht offen legen möchten, können Sie den Header den verschlüsselten Daten voranstellen. –

+0

Sie sollten einen abgeleiteten Schlüssel anstelle eines Hash des Kennworts verwenden. –

Antwort

0

Wenn der Dateityp durch die Verschlüsselung verborgen werden muss oder nicht, ist eine Benutzeranforderung erforderlich. Sie möchten vielleicht nur den Inhalt und nicht den Dateityp schützen. Beachten Sie, dass die Dateigröße auch Hinweise für einen "Angreifer" geben kann. Es liegt auch an Ihnen, ob Sie diese Art von Metadaten verstecken müssen.

Ohne die Erweiterung können Sie den Dateiinhalt mit Datei Fingerabdruck betrachten. Viele Dateiformate geben einen Hinweis darauf, was sie sind. Zum Beispiel ist es sicher möglich, die Zeichencodierung von TXT-Dateien zu erraten. JPG-Dateien haben JPG-Header, dasselbe gilt für Zip-Archive usw. Normalerweise geben diese Tools den MIME-Dateityp aus (da die Erweiterung nicht immer genau definiert oder standardisiert ist).

Auf GNU-Systemen können Sie dafür die Befehlszeile file verwenden. Diese Art von Fingerabdrücken wird auch für viele Content-Management-Systeme (CMS) verwendet. Sie können sich also das CMS in Ihrer Sprache ansehen und versuchen, die darin enthaltene Befehlsfunktion file herauszufiltern.

Oder, jetzt kennen Sie die richtigen Suchbegriffe, Sie können es einfach hier auf StackOverflow finden: Using .NET, how can you find the mime type of a file based on the file signature not the extension wurde als 3. Treffer bei der Eingabe von "Fingerabdruck-Datei Typ C# Mime" gegeben.

Beachten Sie, dass, weil Erweiterungen nicht immer so gut definiert sind, Sie die ursprüngliche Erweiterung möglicherweise nicht auf diese Weise erhalten. Um dies zu ermöglichen, müssen Sie die Erweiterung im Klartext (im Dateinamen) speichern, um die Größe des Dateinamens (!) Zu erhöhen, oder Sie können sie zusammen mit den Daten verschlüsselt speichern. Sie müssten dafür ein Verschlüsselungsprotokoll erstellen.