Hallo liebe Community!
Ich beschäftige mich zur Zeit mit einem kleinen Tool, welches Dateien ver- & entschlüsseln kann. Dazu nutze ich die in System.Security.Cryptography bereitgestellte Klasse RijndaelManaged. Kleinere Dateien (<2GB) kann ich problemlos ver- und entschlüsseln.
Dateien, welche größer als 2GB sind, können jedoch nur mit Hilfe eines Streams (FileStream, CryptoStream etc.) verschlüsselt werden, wo ich zu meinem Problem komme: In jeglichen Beschreibungen die ich bislang finden konnte, werden große Dateien mit Hilfe eines 'In'- und 'Out'-Streams verschlüsselt. Dazu habe ich folgendes Beispiel:
void Encrypt( string path ) { using ( var fsOut = new FileStream( path + ".crypt", FileMode.Create ) ) { using ( var fsIn = new FileStream( path, FileMode.Open ) ) { using ( var aes = new RijndaelManaged() ) { var key = new Rfc2898DeriveBytes( _pass, _salt, 1000 ); aes.KeySize = _keysize; aes.BlockSize = 128; aes.Key = key.GetBytes( aes.KeySize / 8 ); aes.IV = key.GetBytes( aes.BlockSize / 8 ); aes.Mode = CipherMode.CBC; using ( var cs = new CryptoStream( fsOut, aes.CreateEncryptor(), CryptoStreamMode.Write ) ) { int data; while ( ( data = fsIn.ReadByte() ) != -1 ) { cs.WriteByte( ( byte )data ); } } } } } File.Delete( path ); }
Jedoch war mein Ziel, die Datei 'in sich' zu verschlüsseln, also keine neue Datei dabei anzulegen und die alte dann zu löschen
Mein nächster Versuch, nur mit einem FileStream erbrachte zwar ansatzweise das gewünschte Ergebnis, jedoch wurde der verschlüsselte Inhalt einfach dem original Inhalt angefügt, was mir Codetechnisch auch einleuchtet:
void Encrypt( string path ) { using ( var fs = new FileStream( path, FileMode.Open, FileAccess.ReadWrite, FileShare.None ) ) { using ( var aes = new RijndaelManaged() ) { var key = new Rfc2898DeriveBytes( _pass, _salt, 1000 ); aes.KeySize = _keysize; aes.BlockSize = 128; aes.Key = key.GetBytes( aes.KeySize / 8 ); aes.IV = key.GetBytes( aes.BlockSize / 8 ); aes.Mode = CipherMode.CBC; using ( var cs = new CryptoStream( fs, aes.CreateEncryptor(), CryptoStreamMode.Write ) ) { int data; while ( ( data = fs.ReadByte() ) != -1 ) { cs.WriteByte( ( byte )data ); } } } } }
Meine Frage nun: Kennt jemand einen Weg, große Dateien in sich zu verschlüsseln und könnte mir den Weg dazu erklären?
Vielen Dank im Voraus!
Mit freundlichen Grüßen,
fl4shx
Edit:
Ich war zu voreilig. Das ganze funktioniert auch mit zwei FileStreams, jedoch sollte man dann 'FileShare' auf 'ReadWrite' setzen *facepalm*
Für alle die mal große Dateien verschlüsseln müssen, hier mein Code:
public void EncryptFile( string path ) { try { using ( var aes = new RijndaelManaged() ) { var key = new Rfc2898DeriveBytes( _pass, _salt, 1000 ); aes.KeySize = _keysize; aes.BlockSize = 128; aes.Key = key.GetBytes( aes.KeySize / 8 ); aes.IV = key.GetBytes( aes.BlockSize / 8 ); aes.Mode = CipherMode.CBC; using ( var fsIn = new FileStream( path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite ) ) { using ( var fsOut = new FileStream( path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite ) ) { using ( var cs = new CryptoStream( fsOut, aes.CreateEncryptor(), CryptoStreamMode.Write ) ) { int data; while ( ( data = fsIn.ReadByte() ) != -1 ) { cs.WriteByte( ( byte )data ); } } } } } File.Move( path, path + ".crypto" ); } catch ( Exception ex ) { //TODO } }
Bearbeitet von fl4shx, 25 May 2018 - 16:35 Uhr.