Eccezione C # “Dati errati” durante la decodifica del file crittografato

Ehi, sono molto nuovo alla crittografia e alla decrittografia, o anche al linguaggio c # per essere onesto. Fondamentalmente, ho un server di chat TCP che “salva” i registri e crittografa il file di testo. Questo è il modo in cui crittografo (basato sull’esempio MSDN):

public static void EncryptFile(string strInputFileName, string strOutputFileName, string strKey) { FileStream fsIn = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read); FileStream fsOut = new FileStream(strOutputFileName, FileMode.Create, FileAccess.Write); DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.Key = ASCIIEncoding.ASCII.GetBytes(strKey); des.IV = ASCIIEncoding.ASCII.GetBytes(strKey); ICryptoTransform desencrypt = des.CreateEncryptor(); CryptoStream cryptostream = new CryptoStream(fsOut, desencrypt, CryptoStreamMode.Write); byte[] byteArrayInput = new byte[fsIn.Length - 1]; fsIn.Read(byteArrayInput, 0, byteArrayInput.Length); cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length); fsIn.Close(); fsOut.Close(); } 

Il metodo successo crittografa completamente i file. Questo è il mio metodo decrypt:

 public static void DecryptFile(string strInputFileName, string strOutputFileName, string strKey) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.Key = ASCIIEncoding.ASCII.GetBytes(strKey); des.IV = ASCIIEncoding.ASCII.GetBytes(strKey); byte[] te = new byte[1024]; FileStream fsRead = new FileStream(strInputFileName, FileMode.Open, FileAccess.Read); ICryptoTransform desdecrypt = des.CreateDecryptor(); CryptoStream cryptostream = new CryptoStream(fsRead, desdecrypt, CryptoStreamMode.Read); StreamWriter fsDecrypted = new StreamWriter(strOutputFileName); fsDecrypted.Write(new StreamReader(cryptostream).ReadToEnd());//This is where the "Bad Data" occurs. fsDecrypted.Flush(); fsDecrypted.Close(); fsRead.Close(); } 

E quando ispeziono l’object cryptostream, dice che ha generato un’eccezione, “Stream non supporta la ricerca”.

Qualsiasi aiuto sarebbe molto apprezzato!

Qui:

  cryptostream.Write(byteArrayInput, 0, byteArrayInput.Length); fsIn.Close(); fsOut.Close(); 

Stai chiudendo fsOut direttamente, senza chiudere cryptostream . Ciò significa che il stream crittografico non ha la possibilità di svuotare eventuali blocchi finali, ecc.

Inoltre:

  • Utilizzare le istruzioni invece di chiamare manualmente Chiudi o Disponi
  • Attualmente stai chiamando Read una volta, e assumendo che leggerà tutti i dati – non stai controllando il valore restituito. (Stai anche rimuovendo l’ultimo byte del file di input per qualche motivo … perché?) In generale, dovresti eseguire il ciclo, leggere in un buffer e poi scrivere comunque molti byte che leggi, finché il metodo Read restituisce 0 Se stai usando .NET 4, Stream.CopyTo è tuo amico.
  objCryptStream.CopyTo(stream); 

Ha funzionato per me, il codice completo è

  public static string DecryptString(string encriptedText, string key) { try { //Convert the text into bytest byte[] ecriptedBytes = System.Convert.FromBase64String(encriptedText); // Create a memory stream to the passed buffer MemoryStream objMemStream = new MemoryStream(ecriptedBytes); //Set the legal keys and initialization verctors objCrptoService.Key = GetLegalsecretKey(key); objCrptoService.IV = GetLegalIV(); // Create a CryptoStream using the memory stream and the cryptographic service provider version // of the Data Encryption stanadard algorithm key CryptoStream objCryptStream = new CryptoStream(objMemStream, objCrptoService.CreateDecryptor(), CryptoStreamMode.Read); // Create a StreamReader for reading the stream. //StreamReader objstreamReader = new StreamReader(objCryptStream); MemoryStream stream = new MemoryStream(); objCryptStream.CopyTo(stream); stream.Position = 0; StreamReader R = new StreamReader(stream); string outputText = R.ReadToEnd(); // Close the streams. R.Close(); objCryptStream.Close(); objMemStream.Close(); return outputText; } catch (Exception exc) { return ""; } } 

Quello che ha risolto il mio problema è stato chiamare FlushFinalBlock su cryptostream, durante la creazione del file

  CryptoStream cryptostream = new CryptoStream(memoryStream, this._encryptionKeyHelper.Encryptor(), CryptoStreamMode.Write); xmlser.Serialize(cryptostream, builderObject); cryptostream.FlushFinalBlock();