views:

29

answers:

3

So the basic question is in encrypting files in resource constrained devices. I have used a rather dangerous approach to use two FileStreams, where

  1. FileStream 1 is reading from the file and copying it to a byte array
  2. The contents of the byte array is encrypted.
  3. FileStream 2, writes the bytes back to the same file.

This works fine but has a great chance of messing up a file if the encryption stops halfway etc.

So the normal approach is to write to a temp file, and then move it to the original location and replacing the original file.

However the problem is in mobile phones where resources (especially storage) are very limited, creating lets say another 200MB or 300MB file maybe impossible.

So what approaches are there to handle this problem in Mobile Devies? Do I have to gamble between space and messing up the file?

+1  A: 

First of all, you can always check if there is enough space to write your array to a tmp file.

Next, the problem you ask is not a real problem since if you're encrypting, you have read the complete file to array. Once encryption is finished, you can be sure that the byte array is encrypted. If this was not the case, the function would throw an exception. So, in step 3, when you write to file, you can overwrite it.

edit I now realize that you encrypt and write to file partially since otherwise it wouldn't fit into ram. Is that correct?

Henri
Yes. I take part by part -> Encrypt a part and write that part back to the file.
Ranhiru Cooray
+2  A: 

One way to make the process a little safer, could be to:

  1. FileStream 1 is reading from the file and copying it to a byte array
  2. The bytes you read, is written to a small "scratch" file the same size as your buffer, along with position of last block succesfully read.
  3. The contents of the byte array is encrypted.
  4. FileStream 2, writes the bytes back to the same file.

If the process is interrupted, check in the scratch file to see where your last position was. Then you can re-start the process from there, and still be able to encrypt the whole file. (And if you wanted to get the original file back, you would encrypt the remaining blocks, then decrypt it).

Of course, this process only works if you are using an encryption algorithm, that relies on the result of the preceding blocks when encrypting the current block. Depending on your choice of algorithm, you might need to store a little bit more.

driis
Yes. I am using Cipher Block Chaining as my mode of operation which relies on the previous block for encrypting the current block. This sounds promising. I should give this a try :)
Ranhiru Cooray
+1  A: 

Do I have to gamble between space and messing up the file?

Basically, Yes.
If space-constraints force you to convert (encrypt) in-place, there is no rollback option.

The next problem is Size. If your conversion (can) increase the size of the data, you have very limited room to maneuver. If ResultSize > (InputSize + Buffer) Then you're not going to succeed.

In the case of encryption, you can use a CompressStream in front of the CryptoStream, but you won't be able to predict if it's going to work.

In short, on a Mobile device you have reached a limit. You will have to mandate an extra Memory device.

Henk Holterman
The encrypted file would be the same size as the original file, if that's what you are asking :) At the end of the encryption process, ResultSize = InputSize.
Ranhiru Cooray
@Ranhiru: You're probably right about encryption maintaining the same size.
Henk Holterman