0

I'm using the following example:

http://compscipleslab.wordpress.com/category/java/

But I'm getting an exception and when I log the exceptions it it appears in my logcat stating: InvalidKeyException

I'm not sure exactly what I've done wrong. I haven't really modified the methods from the tutorial (perhaps this is the problem) so I'm not sure exactly why I'm getting this error.

Source:

   public class FileChooser extends ListActivity {

    private File currentDir;
    private File moveToDir;
    private FileArrayAdapter adapter;
    public static String TAG = "DEBUG THIS:";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        currentDir = new File("/sdcard/");
        fill(currentDir);
        registerForContextMenu(getListView());
        // get the attachment's filename
        SharedPreferences preferences = PreferenceManager
                .getDefaultSharedPreferences(this);
        String attachmentFileName = preferences.getString("fileName", "");

        // save the attachment
        try {
            InputStream attachment = getContentResolver().openInputStream(
                    getIntent().getData());

            File savedFile = new File(Environment.getExternalStorageDirectory()
                    .getAbsolutePath(), attachmentFileName);
            FileOutputStream f = new FileOutputStream(savedFile);
            byte[] buffer = new byte[1024];
            int len1 = 0;
            while ((len1 = attachment.read(buffer)) > 0) {
                f.write(buffer);
            }
            f.close();
        } catch (Exception e) {
        }
    }

    // File Manager Source to view SD Card or Internal Storage Contents
    private void fill(File f) {
        File[] dirs = f.listFiles();
        this.setTitle("Current Dir: " + f.getName());
        List<Item> dir = new ArrayList<Item>();
        List<Item> fls = new ArrayList<Item>();
        try {
            for (File ff : dirs) {
                Date lastModDate = new Date(ff.lastModified());
                DateFormat formater = DateFormat.getDateTimeInstance();
                String date_modify = formater.format(lastModDate);
                if (ff.isDirectory()) {

                    File[] fbuf = ff.listFiles();
                    int buf = 0;
                    if (fbuf != null) {
                        buf = fbuf.length;
                    } else
                        buf = 0;
                    String num_item = String.valueOf(buf);
                    if (buf == 0)
                        num_item = num_item + " item";
                    else
                        num_item = num_item + " items";

                    // String formated = lastModDate.toString();
                    dir.add(new Item(ff.getName(), num_item, date_modify, ff
                            .getAbsolutePath(), "directory_icon"));
                } else {

                    fls.add(new Item(ff.getName(), ff.length() + " Byte",
                            date_modify, ff.getAbsolutePath(), "file_icon"));
                }
            }
        } catch (Exception e) {

        }
        Collections.sort(dir);
        Collections.sort(fls);
        dir.addAll(fls);
        if (!f.getName().equalsIgnoreCase("sdcard"))
            dir.add(0, new Item("..", "Parent Directory", "", f.getParent(),
                    "directory_up"));
        adapter = new FileArrayAdapter(FileChooser.this, R.layout.file_view,
                dir);
        this.setListAdapter(adapter);
    }

    // onClick listener to move back one directory
    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        Item o = adapter.getItem(position);
        if (o.getImage().equalsIgnoreCase("directory_icon")
                || o.getImage().equalsIgnoreCase("directory_up")) {
            currentDir = new File(o.getPath());
            fill(currentDir);
        } else {
            onFileClick(o);
        }
    }

    // open file onClick
    private void onFileClick(Item o) {

        Intent intent = new Intent();
        intent.putExtra("GetPath", currentDir.toString());
        intent.putExtra("GetFileName", o.getName());
        setResult(RESULT_OK, intent);
        finish();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Context Menu");
        menu.add(0, v.getId(), 0, "Copy");
        menu.add(0, v.getId(), 0, "Paste");
        menu.add(0, v.getId(), 0, "Delete");
        menu.add(0, v.getId(), 0, "Encrypt");
        menu.add(0, v.getId(), 0, "Decrypt");
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (item.getTitle() == "Copy") {
            function1(item.getItemId());
        }
        if (item.getTitle() == "Paste") {
            function2(item.getItemId());
        }
        if (item.getTitle() == "Delete") {
            function3(item.getItemId());
        }
        if (item.getTitle() == "Encrypt") {
            function4(item.getItemId());
        }
        if (item.getTitle() == "Decrypt") {
            function5(item.getItemId());
        } else {
        }
        return false;

    }

    public void function1(int id) {
        Toast.makeText(this, "Copy", Toast.LENGTH_SHORT).show();

        try {

            File sd = Environment.getExternalStorageDirectory();
            currentDir = new File(sd.getAbsolutePath());
            moveToDir = new File(sd.getAbsolutePath());
            copyDirectoryOneLocationToAnotherLocation(currentDir, currentDir);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void function2(int id) {

        Toast.makeText(this, "Paste", Toast.LENGTH_SHORT).show();
    }

    public void function3(int id) {
        Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show();
        DeleteRecursive(currentDir);
    }

    public void function4(int id) {
        Toast.makeText(this, "Encrypt", Toast.LENGTH_SHORT).show();
        //encrypt(null, null, null);
        // encrypt(String PlaintextFile, String Key, String CiphertextFile);
          encrypt("D:\\plaintext.txt", "testkey", "D:\\ciphertext.txt");
    }

    public void function5(int id) {
        Toast.makeText(this, "Decrypt", Toast.LENGTH_SHORT).show();
        decrypt(null, null, null);
        // decrypt(String PlaintextFile, String Key, String CiphertextFile);

    }

    private void DeleteRecursive(File fileOrDirectory) {

        if (fileOrDirectory.isDirectory()) {
            File[] children = fileOrDirectory.listFiles();
            if (null != children) {
                for (File child : children)
                    DeleteRecursive(child);
            }
        }

        fileOrDirectory.delete();

    }

    public static void copyDirectoryOneLocationToAnotherLocation(
            File sourceLocation, File targetLocation) throws IOException {

        if (sourceLocation.isDirectory()) {
            if (!targetLocation.exists()) {
                targetLocation.mkdir();
            }

            String[] children = sourceLocation.list();
            for (int i = 0; i < sourceLocation.listFiles().length; i++) {

                copyDirectoryOneLocationToAnotherLocation(new File(
                        sourceLocation, children[i]), new File(targetLocation,
                        children[i]));
            }
        } else {

            InputStream in = new FileInputStream(Environment
                    .getExternalStorageDirectory().getPath());

            OutputStream out = new FileOutputStream(Environment
                    .getExternalStorageDirectory().getPath());
            Log.d("TEST", "source: " + in);
            Log.d("TEST", "target: " + out);

            // Copy the bits from instream to outstream
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();
        }

    }

    public static void encrypt(String PlaintextFile, String Key,
            String CiphertextFile) {
        try {
            byte[] KeyData = Key.getBytes();
            SecretKeySpec KS = new SecretKeySpec(KeyData, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, KS);
            FileInputStream fis = new FileInputStream(PlaintextFile);
            CipherInputStream cis = new CipherInputStream(fis, cipher);
            FileOutputStream fos = new FileOutputStream(CiphertextFile);
            byte[] b = new byte[1024];
            int i = cis.read(b);
            while (i != -1) {
                fos.write(b, 0, i);
                i = cis.read(b);
            }
            fos.flush();
            fos.close();
            fis.close();
            cis.close();
            System.out.println("Encryption Successfull !!!");

        } catch (NoSuchAlgorithmException exception) {
            // do something.

            Thread.currentThread().getStackTrace();
        } catch (NoSuchPaddingException exception) {
            // do something (else?).
            Thread.currentThread().getStackTrace();
        } catch (InvalidKeyException exception) {
            // do something.
            Thread.currentThread().getStackTrace();
        } catch (IOException exception) {
            // do something (else?).
            Thread.currentThread().getStackTrace();

        }

    }

    public static void decrypt(String CiphertextFile, String Key,
            String DecipheredFile) {
        try {
            byte[] KeyData = Key.getBytes();
            SecretKeySpec KS = new SecretKeySpec(KeyData, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, KS);
            FileInputStream fis = new FileInputStream(CiphertextFile);
            FileOutputStream fos = new FileOutputStream(DecipheredFile);
            CipherOutputStream cos = new CipherOutputStream(fos, cipher);
            byte[] b = new byte[1024];
            int i = fis.read(b);
            while (i != -1) {
                cos.write(b, 0, i);
                i = fis.read(b);
            }
            fos.flush();
            fos.close();
            fis.close();
            cos.flush();
            cos.close();
            System.out.println("Decryption Successfull !!!");

        } catch (NoSuchAlgorithmException exception) {
            // do something.

            Thread.currentThread().getStackTrace();
        } catch (NoSuchPaddingException exception) {
            // do something (else?).
            Thread.currentThread().getStackTrace();
        } catch (InvalidKeyException exception) {
            // do something.
            Thread.currentThread().getStackTrace();
        } catch (IOException exception) {
            // do something (else?).
            Thread.currentThread().getStackTrace();

        }

    }
     public static void main(String[] args) {
            encrypt("D:\\plaintext.txt", "testkey", "D:\\ciphertext.txt");
            decrypt("D:\\ciphertext.txt", "testkey", "D:\\originaltext.txt");
        }
}

LOGCAT:

01-14 17:53:07.904: I/SurfaceTextureClient(9545): [STC::queueBuffer] (this:0x5f1c6d58) fps:6.11, dur:2780.41, max:2503.10, min:13.29
01-14 17:53:07.905: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:07.905: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:07.958: V/Provider/Settings(9545): invalidate [system]: current 6 != cached 0
01-14 17:53:07.963: V/Provider/Settings(9545): from db cache, name = sound_effects_enabled , value = 0
01-14 17:53:07.966: D/skia(9545): Flag is not 10
01-14 17:53:07.976: W/System.err(9545): java.security.InvalidKeyException: Key length not 128/192/256 bits.
01-14 17:53:07.983: W/System.err(9545):     at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:578)
01-14 17:53:07.983: W/System.err(9545):     at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineInit(BaseBlockCipher.java:625)
01-14 17:53:07.983: W/System.err(9545):     at javax.crypto.Cipher.init(Cipher.java:519)
01-14 17:53:07.983: W/System.err(9545):     at javax.crypto.Cipher.init(Cipher.java:479)
01-14 17:53:07.983: W/System.err(9545):     at com.idg.voiscphone.FileChooser.encrypt(FileChooser.java:276)
01-14 17:53:07.984: W/System.err(9545):     at com.idg.voiscphone.FileChooser.function4(FileChooser.java:209)
01-14 17:53:07.984: W/System.err(9545):     at com.idg.voiscphone.FileChooser.onContextItemSelected(FileChooser.java:169)
01-14 17:53:07.984: W/System.err(9545):     at android.app.Activity.onMenuItemSelected(Activity.java:2597)
01-14 17:53:07.984: W/System.err(9545):     at com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback.onMenuItemSelected(PhoneWindow.java:3663)
01-14 17:53:07.984: W/System.err(9545):     at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:735)
01-14 17:53:07.985: W/System.err(9545):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:149)
01-14 17:53:07.985: W/System.err(9545):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:874)
01-14 17:53:07.985: W/System.err(9545):     at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:167)
01-14 17:53:07.985: W/System.err(9545):     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:963)
01-14 17:53:07.985: W/System.err(9545):     at android.widget.AdapterView.performItemClick(AdapterView.java:298)
01-14 17:53:07.985: W/System.err(9545):     at android.widget.AbsListView.performItemClick(AbsListView.java:1128)
01-14 17:53:07.986: W/System.err(9545):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:2812)
01-14 17:53:07.986: W/System.err(9545):     at android.widget.AbsListView$1.run(AbsListView.java:3571)
01-14 17:53:07.986: W/System.err(9545):     at android.os.Handler.handleCallback(Handler.java:725)
01-14 17:53:07.986: W/System.err(9545):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-14 17:53:07.986: W/System.err(9545):     at android.os.Looper.loop(Looper.java:153)
01-14 17:53:07.987: W/System.err(9545):     at android.app.ActivityThread.main(ActivityThread.java:5297)
01-14 17:53:07.987: W/System.err(9545):     at java.lang.reflect.Method.invokeNative(Native Method)
01-14 17:53:07.987: W/System.err(9545):     at java.lang.reflect.Method.invoke(Method.java:511)
01-14 17:53:07.987: W/System.err(9545):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
01-14 17:53:07.988: W/System.err(9545):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
01-14 17:53:07.988: W/System.err(9545):     at dalvik.system.NativeStart.main(Native Method)
01-14 17:53:07.989: D/OpenGLRenderer(9545): Flushing caches (mode 0)
01-14 17:53:08.013: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.013: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.028: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.028: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.052: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.053: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.054: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.076: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.076: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.076: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.078: V/InputMethodManager(9545): onWindowFocus: android.widget.ListView{4206e2c0 VFED.VCL .F...... 0,0-720,1126 #102000a android:id/list} softInputMode=16 first=false flags=#1810100
01-14 17:53:08.091: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.091: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.091: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.092: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.092: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.092: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.097: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
01-14 17:53:08.102: W/Trace(9545): Unexpected value from nativeGetEnabledTags: 0
user3183409
  • 45
  • 1
  • 2
  • 7

2 Answers2

1

One problem with your code is your specified Algorithms for Cipher and SecretKeySpec instances are not the same. You are mixing 2 different algorithms up.

As in the reference example, keep it same for both the instances:

Incorrect lines:

SecretKeySpec KS = new SecretKeySpec(KeyData, "Blowfish");
Cipher cipher = Cipher.getInstance("AES");

You can consider reading AES vs Blowfish here.

EDIT:

As indicated, strictly AES would be used throughout the solution. Hence, the key which you are setting isn't a valid AES key - AES keys are 128, 192 or 256 bits (as evident from your exception as well). That would mean your current key should be of 16, 24 or 32 bytes (though testkey is 7).

Consider the following:

  1. Follow the reference and change the algorithm to Blowfish which would accept your key
  2. Try changing your key to a 16 byte (example: ThisSecurityKey1). There can be considerations of your character encoding (UTF-8, UTF-16) but since you're using plain text, it should work.
  3. Lookup KeyGenerator class, useful to generate symmetric keys.

This class provides the functionality of a secret (symmetric) key generator.

Also, try and refer to a better encryption example of AES - the reference you've selected is full of non-compliant Java coding standards.

Community
  • 1
  • 1
StoopidDonut
  • 8,547
  • 2
  • 33
  • 51
  • Thanks! (That was a terrible mistake) I updated my source and ran it again... I'm still getting the invalidkeyexception – user3183409 Jan 14 '14 at 22:13
  • @user3183409 What algorithm are you using now? I think then the stacktrace of the exception would be a start – StoopidDonut Jan 14 '14 at 22:17
  • Strictly AES (I updated my source above) I'll post the stacktrace now – user3183409 Jan 14 '14 at 22:18
  • I posted it - I dont see anything useful in it - do you? – user3183409 Jan 14 '14 at 22:24
  • Thread.currentThread().getStackTrace(); should do the trick, right? – user3183409 Jan 14 '14 at 22:29
  • since you're catching `Exception`s, you should do `exception.printStackTrace();` – Embattled Swag Jan 14 '14 at 22:45
  • @user3183409 I tried to give a few options, please refer to the edited answer. – StoopidDonut Jan 14 '14 at 23:12
  • Excellent! Thank you! This was VERY helpful! One little question... do you know where I can find a solid AES 256 example? (I'm not sure exactly what I should or shouldn't be looking for - it's my first time using it) – user3183409 Jan 15 '14 at 15:57
  • @user3183409 I'd prefer interactive discussions on SO itself for a thorough understanding, to start with refer to [here](http://stackoverflow.com/questions/992019/java-256-bit-aes-password-based-encryption), good luck! – StoopidDonut Jan 15 '14 at 16:01
  • Quick question - how did you determine testkey is 7? (I'm trying to change it to 256 bit but I dont understand the logic behind using ThisSecurityKey1 as you mentioned.) – user3183409 Jan 15 '14 at 16:41
  • @user3183409 depends on your String, so for 256 bits you need to have 256/8 = 32 bytes. I gave you an example for 16 bytes. More information [here](http://stackoverflow.com/questions/4385623/bytes-of-a-string-in-java) – StoopidDonut Jan 15 '14 at 16:49
1

Another problem with your code is here:

while ((len1 = attachment.read(buffer)) > 0) {
    f.write(buffer);
}

This will write junk at the end of the target unless the size is a multiple of the buffer size. It should be:

while ((len1 = attachment.read(buffer)) > 0) {
    f.write(buffer, 0, len1);
}
Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
user207421
  • 305,947
  • 44
  • 307
  • 483