0

I am trying to encrypt a byte[] using the following methods but when I decrypt it my byte[] is bigger than when I started and I think its to do with padding but I am not sure how to solve it.

The method isnt finished yet (I know its bad to append the key + iv like my example but its for testing purpose to get it working before I move on).

So when I try to open the file afterwards (tested with MS Word file) I get a message saying the file is damaged and would I like to repair it.

Encrypt Method

public byte[] Encrypt(byte[] dataToEncrypt) {
        // Check arguments. 
        if (dataToEncrypt == null || dataToEncrypt.Length <= 0) {
            throw new ArgumentNullException("dataToEncrypt");
        }

        byte[] encryptedData;
        byte[] key;
        byte[] iv;

        // Create an Aes object  
        using (Aes aesAlg = Aes.Create()) {
            key = aesAlg.Key;
            iv = aesAlg.IV;

            // Create a encrytor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption. 
            using (MemoryStream memoryStream = new MemoryStream()) {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) {
                    cryptoStream.Write(dataToEncrypt, 0, dataToEncrypt.Length);
                    cryptoStream.FlushFinalBlock();

                    encryptedData = memoryStream.ToArray();

                }
            }


        }

        byte[] result = new byte[encryptedData.Length + KEY_SIZE + IV_SIZE];

        Buffer.BlockCopy(key, 0, result, 0, KEY_SIZE);
        Buffer.BlockCopy(iv, 0, result, KEY_SIZE, IV_SIZE);
        Buffer.BlockCopy(encryptedData, 0, result, KEY_SIZE + IV_SIZE, encryptedData.Length);

        return result;
    }

Decrypt Method

public byte[] Decrypt(byte[] encryptedData) {
        // Check arguments. 
        if (encryptedData == null || encryptedData.Length <= 0) {
            throw new ArgumentNullException("encryptedData");
        }

        byte[] storedKey = new byte[KEY_SIZE];
        byte[] storedIV = new byte[IV_SIZE];
        byte[] dataToDecrypt = new byte[encryptedData.Length - (KEY_SIZE + IV_SIZE)];

        Buffer.BlockCopy(encryptedData, 0, storedKey, 0, KEY_SIZE);
        Buffer.BlockCopy(encryptedData, KEY_SIZE, storedIV, 0, IV_SIZE);
        Buffer.BlockCopy(encryptedData, KEY_SIZE + IV_SIZE, dataToDecrypt, 0, encryptedData.Length - (KEY_SIZE + IV_SIZE));

        byte[] decryptedData = null;

        // Create an AesCryptoServiceProvider object 
        // with the specified key and IV. 
        using (Aes aesAlg = Aes.Create()) {
            aesAlg.Key = storedKey;
            aesAlg.IV = storedIV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for decryption. 
            using (MemoryStream memoryStream = new MemoryStream(dataToDecrypt)) {
                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) {
                    cryptoStream.Read(dataToDecrypt, 0, dataToDecrypt.Length);

                    decryptedData = memoryStream.ToArray();
                }
            }

        }

        return decryptedData;
    }
President James K. Polk
  • 40,516
  • 21
  • 95
  • 125
Stephen E.
  • 252
  • 2
  • 17

1 Answers1

0

You are assuming that the entire buffer is plaintext data as well. You should only return that part of the buffer that contains the plaintext data (using the response of Read to see how much bytes are returned). The encrypted data is usually larger because of the padding.

As a single read method isn't good practice with regards to stream handling. You need to read until the end of the stream is reached. Otherwise you may go from having too much data to having too little.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I knew it was something to do with padding but couldnt work out how to do it, alot of examples I found was about encrypting/decrypting strings. Could you give a small example of what should be inside the CryptoStream? I seen a few examples which said do string plainText = cryptoStream.ReadToEnd() and then get the bytes from the plainText but that didnt work (I cant remember the error it gave me as I am not at my laptop with the code). – Stephen E. Jan 13 '15 at 09:08