2

I am new in Android, and I´m making an app and I want to focus on the secure of the app, I found this link, in it says "keep sensitive information in RAM for the minimum time possible by setting it to null after use." and later it says "avoid the use of Java’s String class to hold sensitive information. Instead use char arrays or byte arrays. The reason for this is because Strings are immutable"

In my app I have a code similar to this (this code just checks a PIN the users enters and compares it with another one in the internal storage):

public class Class extends Activity implements OnClickListener{
    private static final String fileName = "FilePin";
    private Button button;
    private EditText editText = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_example); 
        editText = (editText) findViewById(R.id.editText); 
        button = (Button) findViewById(R.id.button);  
        button.setOnClickListener(this);
    }   

    @Override
    public void onClick(View v){
        if (readPin()) {
            textView.setText(new char[]{' '}, 0, 0);
            Intent intent = new Intent(this, OtherClass.class);  
            startActivity(intent);
        }
    }

//   this method read the file where the PIN the user create is save in the internal storage
    public boolean readPin(){
        StringBuilder stringBuilder = null;
        StringBuilder inputString;
        try {
            BufferedReader inputReader = new BufferedReader(new InputStreamReader
                    (openFileInput(fileName)));
            stringBuilder = new StringBuilder();
            while ((inputString = new StringBuilder(inputReader.readLine())) != null) {
                stringBuilder.append(inputString);
            }
            inputReader.close();
        } catch (Exception e) {
            e.printStackTrace();
            }
        inputString = new StringBuilder("");
        assert stringBuilder != null;
        boolean comparePin = compare(stringBuilder);
        stringBuilder = new StringBuilder("");
        return comparePin;
    }

//  this method compare the PIN saved with the PIN the users enters
    private boolean compare(StringBuilder pinSaved){
        if (!editText.getText().toString().equals(pinSaved.toString())) {
            Toast.makeText(getBaseContext(), "the PIN it´s incorrect"
                    , Toast.LENGTH_SHORT).show();
            pinSaved = new StringBuilder("");
            return false;
        }
        else {
            pinSaved = new StringBuilder("");
            return true;
        }
    }
}

For what I read in the previews link I didn´t use String instead I use StringBuilder because StringBuilder are mutable and after I use it a change the value to "stringBuilder = new StringBuilder("");", I didn´t use char[] because I don´t know how to save the editText to a char[] variable or how to save the PIN saved in the file in a char[] variable and I didn´t find examples about how to use char[] in those cases.

My questions are: this case is secure for an android app or is it better to change to char[] variables?, Is StringBuffer class insecure for Android? How can I save the editText value in a char[]? How Can I save a file in a char[] variable?

  • `StringBuilder` is just a wrapper class for `String`, setting the `StringBuilder` object to null doesn't mean the `String` object it worked with also becomes null. –  Mar 05 '15 at 17:06
  • so it´s better to move to `char[]` or `byte[]` arrays, how can I make a similar methods with arrays? I have tried but I haven´t succeed – Fernando Berra Mar 05 '15 at 17:34
  • You have to declare an array of size 4, because your PIN consists of 4 numbers, and with every click on the numpad you have to fill the array with that number. –  Mar 05 '15 at 17:41
  • So using the method `editText.setOnEditorActionListener(new OnEditorActionListener() {...}` I think I can make it with just adding `pin[i] = actionId;` but the `actionId` its an int parameter I think it is the ASCII code of the key pressed right?, – Fernando Berra Mar 05 '15 at 18:38
  • You should not use an `EditText`, it uses a String property where the typed in code is stored in, instead of Android controls like `EditText`s create your own or Google for a PIN-view library or something like that –  Mar 05 '15 at 20:07
  • I don´t think I am able to make a good PIN-view library with my level right know (honestly I don´t how hard or easy it can be) but I haven´t found what you said "...EditText, it uses a String property where the typed in code is stored in...", I´m not saying it´s not true I really don´t know but I haven´t found any other solutions, and all the PIN-view library I Googled where on a 4 PIN password, I wanted the user could choose any lenght between 6-10 characters, about this topic using EditText on android on sensitive data I have only read to use char[] CharSecuence and byte[] – Fernando Berra Mar 06 '15 at 14:08
  • If so, why did you get this task tho? I can create it for you if you want. –  Mar 06 '15 at 18:35
  • I will thak you a lot if you can create it – Fernando Berra Mar 11 '15 at 16:07

1 Answers1

0
stringBuilder = new StringBuilder("");

The above is weaker than zeroing out a char[]. The original StringBuilder, along with is internal buffer, will stay in memory. At some point, the garbage collector will mark the memory as free, and later still, something might overwrite it.

Zeroing out a char[] gives you more control over when the secret is overwritten.

Also, StringBuilder comes with logic that automatically copies its internal char[] buffer when it needs more room. You need to be careful to make sure it never does this. A plain char[] is inconvenient because you can't resize it, but it's good in this case, because any attempt to copy it is explicit.

See Java: convert a char[] to a CharSequence for how to get your char[] into a form that you can pass to EditText.setText.

Community
  • 1
  • 1
guest
  • 6,450
  • 30
  • 44