2

I have over 1000 images and videos that need to be encrypted. Nothing over the top just something simple, I was thinking of using AES but what I cannot figure out is how to encrypt on my computer then decrypt the item on the device.

I will be encrypting all the items on my computer probably using python. Then in an on demand fashion will decrypt the item with java (Android app)

Any simple explanation will do pseudo code is fine too.

The main issue im having is how to use the same key to encrypt and decrypt. I've been generating the key and can't get it to port to the other device for decryption.

Thanks

Python Code. Works encrypts and decrypts.

from Crypto.Cipher import AES
import os, random, struct

key = '0123456789abcdef'
mode = AES.MODE_CBC
chunksize = 64*1024

iv = ''.join(chr(random.randint(0,0xFF)) for i in range(16))
encryptor = AES.new(key,mode,iv)
filesize = os.path.getsize('sample.jpg')

with open('sample.jpg','rb') as infile:
    with open('sample.enc','wb') as outfile:
       outfile.write(struct.pack('<Q',filesize))
       outfile.write(iv)

    while True:
        chunk = infile.read(chunksize)
        if len(chunk) == 0:
            break
        elif len(chunk) % 16 != 0:
            chunk += ' ' * (16 - len(chunk) % 16)

        outfile.write(encryptor.encrypt(chunk))

## decrypt
with open('sample.enc', 'rb') as infile:
       origsize = struct.unpack('<Q', infile.read(struct.calcsize('Q')))[0]
       iv = infile.read(16)
       decryptor = AES.new(key, AES.MODE_CBC, iv)

       with open('sample2.jpg', 'wb') as outfile:
          while True:
            chunk = infile.read(chunksize)
            if len(chunk) == 0:
                break
            outfile.write(decryptor.decrypt(chunk))

        outfile.truncate(origsize)

How would I do the decrypt part in Java? Here is my quick sloppy java code that doesn't work. I think it is the padding that is messing it up.

  public void decryptFile(){

    String inFile = "sample.enc";
    String outFile = "sample.jpg";
    String dir = Environment.getExternalStorageDirectory() +"/Android/data/HOT/";
    InputStream is ;
    byte[] iv = new byte[16];
    try {
        is = new FileInputStream(dir+inFile);

        is.read(iv);

    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        Log.d("D1","no file found");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        Log.d("D-2","no file found");
        e.printStackTrace();
    }

    byte[] k = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

    Key key = new SecretKeySpec(k,"AES");




    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(iv));
        OutputStream outs = new FileOutputStream(dir+outFile);
        is = new FileInputStream(dir+inFile);
        while(true){
            byte[] chunk = new byte[64*1024];
            is.read(chunk);
            if(chunk.length == 0){

                break;

            }
            outs.write(cipher.doFinal(chunk));              
        }


    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        Log.d("D","1");

        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        Log.d("D","2");
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        Log.d("D","3");
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        // TODO Auto-generated catch block
        Log.d("D","4");
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        Log.d("D","5");
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        Log.d("D","6");
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        Log.d("D","7");
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        Log.d("D","8");
        e.printStackTrace();
    }

    ImageView im = (ImageView)findViewById(R.id.imageView2);

    Bitmap mainBitmap = BitmapFactory.decodeFile(dir+outFile);

    im.setImageBitmap(mainBitmap);

}
user1086377
  • 328
  • 5
  • 16
  • 2
    Why not? What have you tried? – SLaks Feb 23 '12 at 16:32
  • Any reason why you are not using Java on the computer? The Java and Android libs should be compatible, so you can test on your computer only, and you have much less to worry about regarding compatibility between the computer and the device. – Maarten Bodewes Feb 23 '12 at 16:36
  • 1
    Just as an FYI: AES is not a public key cryptographic algorithm (such as RSA), it's a symmetric algorithm, meaning it has only one key (which can both encrypt, and decrypt). – Kitsune Feb 23 '12 at 16:38
  • iirc the bouncycastle provided in android is not fully featured, so be sure to use the X509 spec for pub/private keys, and not any other spec. – platinummonkey Feb 23 '12 at 16:38
  • In future, for example code, it would be better to merge that big list of `catch` blocks into one, so we can see the important bits of the code mor easily. – DNA Feb 23 '12 at 20:17

1 Answers1

1

In the Java version, you don't seem to be reading in the filesize before reading in the IV, unlike the Python version.

You also open a second FileInputStream and then don't skip the filesize and IV before reading in chunks for the Cipher.

Another thing to check is that the keys are being interpreted the same in Java and Python, i.e. the string in Python results in the same sequence of bytes as the byte array in Java.

DNA
  • 42,007
  • 12
  • 107
  • 146