Peter vdL
Peter vdL

Reputation: 4993

Getting a char array from the user without using a String

I want to acquire a password string from the user on Android.

I do not want this string to be stored in a Java String at any point in the process from when the user types it, to where it arrives in my code in a char or byte array.

The reason for this is Sun's injunction against using Java Strings for sensitive data. "Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead." http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx

So I can't use EditText, because that uses Strings internally (even though it returns an Editable which could conceivably be backed by char[] or Char[]?).

What is the simplest way to accept a char array from the user? I'm guessing a Canvas on which I listen for key events?

Upvotes: 12

Views: 3167

Answers (3)

Win Myo Htet
Win Myo Htet

Reputation: 5457

I don't see the EditText.java (API 17) using the String internally. It is merely 2 pages long code. Of course, TextView.java from which EditText has inherited has 9k lines in the file. You still won't see TextView.java using the String internally but with its own implementation of CharWrapper for CharSequence. (TextView.java line #8535 API 17). Here you have the method call getChars. As you will notice that buf is copied over from mChars which is char[] and not String.

    private char[] mChars;
    public void getChars(int start, int end, char[] buf, int off) {
        if (start < 0 || end < 0 || start > mLength || end > mLength) {
            throw new IndexOutOfBoundsException(start + ", " + end);
        }

        System.arraycopy(mChars, start + mStart, buf, off, end - start);
    }

Now all you have to do is call getChar and pass along the char[] to be filled in.

            int pl = mPasswordEt.length();
            char[] password = new char[pl];
            mPasswordEt.getText().getChars(0, pl, password, 0);

You have the desired char[] password without using String. After you have finish working with it you can clear it from memory as follow.

Arrays.fill(password, ' ');

Upvotes: 11

lenik
lenik

Reputation: 23556

There are two possible situations your application may encounter:

  1. All applications are properly sand-boxed in their environment. In this case you should not worry about your passwords, because other processes cannot access your process memory, no matter if there are Strings or byte[] arrays in there.

  2. There's a rogue application with superuser access. In this case you should not worry about Strings either, because there are too many places to intercept your passwords, so Strings should be close to the bottom of the list of things to worry about.

Upvotes: 0

Jason Robinson
Jason Robinson

Reputation: 31284

Editable implements CharSequence, which, according to the docs, is a "readable sequence of char values".

Upvotes: -1

Related Questions