user1086377
user1086377

Reputation: 356

Partial File Encryption

I have a bunch of video files that need to be put onto Android tablets as data for our application. Because we do not want easy access we have decided to encrypt the videos. I'm taking the security through obscurity approach. I started out by encrypting the whole video and decrypting it before playing but quickly it became apparent that loading videos is a big fidelity killer. The user experience and the flow of the application is shot.

I thought maybe I can encrypt the first MB of the video considering all of our videos are over 1MB. If the thief gets their hand on the video at least it isn't the whole thing and is kind of useless.

Bellow is the code that encrypts and decrypts files. It works except for the videos because I'm trying to patch two parts of a file together. The encrypted file seems fine. The decrypted file is off in one spot. I figured that but running them through a diff test.

 public void encrypt(InputStream in, OutputStream out) {
    try {
        // Bytes written to out will be encrypted
       OutputStream out_c = new CipherOutputStream(out, ecipher);

        // Read in the cleartext bytes and write to out to encrypt
        int numRead = 0;
        int count = 0;
        boolean first = true;

        while ((numRead = in.read(buf)) >= 0) {

            if(count <= 1048576){
                count += numRead;
                out_c.write(buf, 0, numRead);
            }else{

                out.write(buf, 0, numRead);

            }
        }
        out.close();
        out_c.close();


    } catch (java.io.IOException e) {
    }
}

// Movies encrypt only 1 MB.

public void decrypt(InputStream in, OutputStream out) {
    try {
        // Bytes read from in will be decrypted
        InputStream in_c = new CipherInputStream(in, dcipher);

        // Read in the decrypted bytes and write the cleartext to out
        int numRead = 0;
        int count = 0;

        while ((numRead = in_c.read(buf)) >= 0 && count <= 1048576) {
            count += numRead;
            out.write(buf, 0, numRead);
        }

        //in.skip(count); This removed 1MB from the final file. No need to skip.

        while((numRead = in.read(buf)) >= 0){

            out.write(buf,0,numRead);

        }

        out.close();
    } catch (java.io.IOException e) {
    }
}

I was wondering if anyone can spot the problem with the encryption or decryption. I know it isn't an ideal solution but it works in our situation.

Thank you.

Upvotes: 1

Views: 1239

Answers (2)

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78639

Well, when you reach this point:

if(count <= 1048576){
   count += numRead;
   out_c.write(buf, 0, numRead);
}

Let say that before the if the count is 1,048,575 (just 1 byte missing to reach the maximum). And you buffer is 1024 bytes. So, when you enter into the if statement, your count end being 1,049,599.

As such, your count can be bigger than 1,048,576. And you need that actual number before reading the file.

Upvotes: 1

sw1nn
sw1nn

Reputation: 7328

You don't stop reading or writing at exactly 1048576 bytes, you read/write whatever portion of your buffer crosses over that threshold. The size of the amount over is not guaranteed to be the same in both the read/write case hence the inconsistency.

Solution is to read in exactly 1048576 bytes of cleartext, write that out through your encryption routine then continue with the rest of the file. Similarly in the decryption case.

Of course you also have to ensure that size(cleartext) == size(ciphertext).

Upvotes: 2

Related Questions