Search code examples
c#encryptionaes

Decryption using CryptoStream returns an empty file


I'm trying to use AES to see how encryption/decryption works. Encrypting files works fine with the following code: (These methods are in two separate files)

        private void tempEncrypt()
        {
            // Creates file with "Test String" inside
            byte[] test = Encoding.ASCII.GetBytes("Test String");
            var file = File.Create("test.txt");
            file.Write(test, 0, test.Length);

            // Saves key and IV for decryption
            var temp = new AesCryptoServiceProvider();
            Console.WriteLine(System.Convert.ToBase64String(temp.Key));
            Console.WriteLine(System.Convert.ToBase64String(temp.IV));

            Encryptor.Encrypt(file, temp.Key, temp.IV);
        }

        public static void Encrypt(FileStream source, byte[] key, byte[] IV)
        {
            // Creates a temp file for encrypting
            var destination = File.Create("encrypted.tmp");
            string path = source.Name;

            using (var provider = new AesCryptoServiceProvider())
            using (var transform = provider.CreateEncryptor(key, IV))
            using (var cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
            {
                // Encrypts file
                source.CopyTo(cryptoStream);
                source.Close();

                // Deletes unencrypted file
                File.Delete(path);
            }
            // Replaces source file with encrypted file
            destination.Close();
            File.Move(destination.Name, path);
            File.Delete(destination.Name);
        }

But when I use this to decrypt the file, the file will be empty:

        private void tempDecrypt()
        {
            // Opens encrypted file
            var file = File.OpenRead("test.txt");
            var temp = new AesCryptoServiceProvider();
            temp.Key = System.Convert.FromBase64String("SANeQe1MK4UKrQmJ4fa16lrhIexK7gaxqE/N/HycdhI=");
            temp.IV = System.Convert.FromBase64String("Pb2SciISBP2p0hWzEUG05A==");
            Encryptor.Decrypt(file, temp.Key, temp.IV);
        }

        public static void Decrypt(FileStream source, byte[] key, byte[] IV)
        {
            // Creates a temp file for decrypting
            var destination = File.Create("decrypted.tmp");
            string path = source.Name;

            Console.WriteLine(source.Length);

            // Decrypts rest of file
            using (var provider = new AesCryptoServiceProvider())
            using (var transform = provider.CreateDecryptor(key, IV))
            using (var cryptoStream = new CryptoStream(source, transform, CryptoStreamMode.Read))
            {
                // Decrypts file
                cryptoStream.CopyTo(destination);
            }
            // Replaces source file with decrypted file
            destination.Close();
            source.Close();
            File.Delete(path);
            File.Move(destination.Name, path);
            File.Delete(destination.Name);
        }

Replacing the file doesn't seem to be the problem because even "decrypted.tmp" is empty before I replace the destination file with the source one.


Solution

  • In the tempEncrypt() method, I had to close the file then re-open using File.OpenRead() for it to decrypt properly. I guess test.txt was still empty even though I used file.Write() to write to the file. Here is the working method:

            private void tempEncrypt()
            {
                // Creates file with "Test String" inside
                byte[] test = Encoding.ASCII.GetBytes("Test String");
                var file = File.Create("test.txt");
                file.Write(test, 0, test.Length);
                
                file.Close();
                var newFile = File.OpenRead("test.txt");
    
                // Saves key and IV for decryption
                var temp = new AesCryptoServiceProvider();
                Console.WriteLine(System.Convert.ToBase64String(temp.Key));
                Console.WriteLine(System.Convert.ToBase64String(temp.IV));
    
                Encryptor.Encrypt(newFile, temp.Key, temp.IV);
            }