0

My requirement is like below. Step 1) I want to write 101 MB data in local file system by encrypting it in chunks of 10-10 MB.

Step 2) While decrypting, I want to fetch 10-10 MB data from file and want to decrypt and want to pass 10-10 MB decrypted it to some other function (Note : My last chunk size would be 1 MB as file size is 101 MB).

So

1) When i try to decrypt only 10 MB it gives error "Padding is invalid and cannot be removed"

2) Now, while decrypt, If i give paddingMode to None then when last chunk comes i.e. 1 MB it gives error "length of the data to decrypt is invalid". Upto 100 MB things are working

Note: 1) Up to 100 MB things are working as expected. If i give last chunk size 10 MB instead of 1 MB then its working but at last my target file size would be 110 MB instead of 101 MB. 2) I am not giving padding mode while encrypting but to avoid padding is invalid error, while decrypting i am giving it to none. Temporary i have commented that code.

3) I am using same key and IV for encryption and decryption

Encryption code :

private void WriteStreamInChunks(Stream fsstream, string filePath)
    {   
        int chunkSize = 10 * 1024 * 1024;
        byte[] buffer = new byte[chunkSize];

        using (var rijndaelManaged = new RijndaelManaged())
        {
            var encryptor = rijndaelManaged.CreateEncryptor(EncryptionKey, EncryptionIV);

            using (var fileStream = File.Create(filePath))
            {
                using (var cryptoStream = new CryptoStream(fileStream, encryptor, CryptoStreamMode.Write))
                {
                    int bytesRead;
                    while ((bytesRead = fsstream.Read(buffer, 0, chunkSize)) > 0)
                    {
                        cryptoStream.Write(buffer, 0, bytesRead);
                    }

                    if (!cryptoStream.HasFlushedFinalBlock)
                        cryptoStream.FlushFinalBlock();
                }
            }
        }
    }

Decryption only chunks and return byte[] Code - Error

"padding is invalid" if i set padding mode zero then length of data invalid exception.

public byte[] GetDecryptedFileContent(string filePath, long chunkSizeInBytes, long seekValue, long fileSize, string encryptionIV)
    {
        var sourceFile = new FileInfo(filePath);
        var buffer = new byte[chunkSizeInBytes];

        byte[] encryptionKey = File.ReadAllBytes(Utils.GetSymmetricAlgoEncryptionKey());

        using (var fileStream = File.Open(sourceFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            fileStream.Seek(seekValue, SeekOrigin.Begin);
            using (var binaryReader = new BinaryReader(fileStream))
            {
                binaryReader.Read(buffer, 0, buffer.Length);
            }
        }

        using (MemoryStream dataOut = new MemoryStream())
        {
            using (RijndaelManaged rijndaelManaged = new RijndaelManaged())
            {
                //rijndaelManaged.Padding = PaddingMode.None;

                ICryptoTransform decryptor = rijndaelManaged.CreateDecryptor(encryptionKey, Convert.FromBase64String(encryptionIV));

                using (CryptoStream cryptoStream = new CryptoStream(dataOut, decryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(buffer, 0, buffer.Length);
                    return dataOut.ToArray();
                }
            }
        }
        return null;
    }

According to my requirement, I must return byte[] from this GetDecryptedFileContent function. I am calling this function multiple time till file size becomes 0. i.e. for every chunk. enter code here Can someone please help me?

i want to return only 10-10 MB.

1 Answers1

0

Input must be a block size multiple or padding must be used. Padding is only added the the last block encrypted. See PKCS#7 padding.

If reading portions of the file at a time make sure the chunk size is a multiple of the block size. On reading specify no padding for all blocks except the last block of the file and specify padding for the last block of the file.

Update: It appears you are using CBC mode because you are using an IV. In that case for all blocks beyond the first block the IV will be the previous block. Just read the previous block and use it for the IV. See CBC mode.

zaph
  • 111,848
  • 21
  • 189
  • 228
  • Thanks for your response. – Dharmesh Fichadiya Sep 18 '17 at 13:53
  • Thanks for your response. What i am trying to do here is 1) I am encrypting all contents in one go and writing it to file. 2) I want to decrypt file in e.g. if file size is 101 MB and chunk size if 20 MB then 20-20 MB i want to decrypt and whatever data are decrypted i want to return it. – Dharmesh Fichadiya Sep 18 '17 at 13:57