Question

I am trying to encode my sharedPreferences username and password using Base64 but when running my program in eclipse emulator, I receive and error message saying "Array out of bounds". I’m not sure what this error means and how to correct it.

Logcat:

10-06 13:51:24.005: E/AndroidRuntime(4272): FATAL EXCEPTION: main
10-06 13:51:24.005: E/AndroidRuntime(4272): java.lang.ArrayIndexOutOfBoundsException: length=3; index=3
10-06 13:51:24.005: E/AndroidRuntime(4272):     at com.SharedPreferences.Login.SharedPrefLoginActivity.onClick(SharedPrefLoginActivity.java:84)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.view.View.performClick(View.java:3511)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.view.View$PerformClick.run(View.java:14105)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.os.Handler.handleCallback(Handler.java:605)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.os.Handler.dispatchMessage(Handler.java:92)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.os.Looper.loop(Looper.java:137)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at android.app.ActivityThread.main(ActivityThread.java:4424)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at java.lang.reflect.Method.invokeNative(Native Method)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at java.lang.reflect.Method.invoke(Method.java:511)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-06 13:51:24.005: E/AndroidRuntime(4272):     at dalvik.system.NativeStart.main(Native Method)

Here is my Registration activity which should take EditText string, encode, and save to sharedpreferences xml.

 public void onClick(View arg0) {
    user=rName.getText().toString().trim();
    pass=rPwd.getText().toString().trim();

    if(arg0==regBttn){     
       if((user.length()!=0))
        {
         if((pass.length()!=0))
            {

        sp=getSharedPreferences("AccessApp",MODE_WORLD_WRITEABLE);
        Editor myEditor=sp.edit();

        try {
            myEditor.putString("USERNAME_KEY", user);
            byte[ ] superSecretKeyBytes = Base64.decode(user);
            byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            for (int i = 0; i < pass.length(); i++) {
                key[i] = superSecretKeyBytes[i];
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }   
        try {
            myEditor.putString("PASSWORD_KEY", pass);
            byte[ ] superSecretKeyBytes = Base64.decode(pass);
            byte[] key = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6 };
            for (int i = 0; i < pass.length(); i++) {
                key[i] = superSecretKeyBytes[i];
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        myEditor.commit();
        Toast.makeText(this, "Registration is successfull",10000).show();
        i=new Intent(this,AccessApp.class);
        startActivity(i);
        }
        else
         {
          Toast.makeText(this, "Please Enter password", 10000).show();  
         }
         }
        else{
            Toast.makeText(this,"Please Enter Username",10000).show();
         }
        }

    else if(arg0==rtnBttn){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
         builder.setTitle("Exit");
         builder.setMessage("Do you want to exit");
         builder.setCancelable(false);
         builder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {

  public void onClick(DialogInterface dialog, int which) {
  // TODO Auto-generated method stub
  finish();
  }
  });
    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {
               arg0.cancel();
            }
        });
    AlertDialog alert=builder.create();
    alert.show();

    }
}
public String encrypt(String toencrypt, byte key[]) throws Exception {
    SecretKeySpec secret = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    byte[] encryptedbytes = cipher.doFinal(toencrypt.getBytes());
    String encrypted = Base64.encodeBytes(encryptedbytes);
    return encrypted;

}
}

Corrections:

  The below corrections were applied.
 (int i = 0; i < superSecretKeyBytes.length && i < key.length; i++)

 Issue:
  Array error has cleared but EditText string is still saved in clear text.?
Was it helpful?

Solution

Why do you use pass length in cycle condition when it is not used inside the cycle? Are you sure that superSecretKeyBytes.length == pass.length()? (probably not equals, you are decoding from Base64)

It is safer to write this:

for (int i = 0; i < superSecretKeyBytes.length; i++) {
    key[i] = superSecretKeyBytes[i];
}

instead of:

for (int i = 0; i < pass.length(); i++) {
    key[i] = superSecretKeyBytes[i];
}

Also, where are any guarantees that you wouldn't get OutOfBoundsException for your key array? Prefer to check this in the cycle as well:

for (int i = 0; i < superSecretKeyBytes.length && i < key.length; i++) {
    key[i] = superSecretKeyBytes[i];
}

OTHER TIPS

When decoding USERNAME_KEY, it looks like you are referencing pass.length instead of user.length as your stop condition in the for loop, i.e. the first instance of:

for (int i = 0; i < pass.length(); i++) {

should be:

for (int i = 0; i < user.length(); i++) {

pass.length() (actually it is pass.length() - 1, technically), is greater than then the positions/locations allocated in the key[] and superSecretKeyBytes[] arrays. So you end up trying to access a location in an array that does not exist, generating the Out of Bounds error.

I think that you're getting out of your key array. You should check that:

pass.length() <= key.length

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top