12

我想从 Android 上的用户那里获取密码字符串。

我不希望这个字符串在从用户键入它到它以 char 或 byte 数组到达我的代码的过程中的任何时候都存储在 Java String 中。

原因是 Sun 禁止将 Java 字符串用于敏感数据。 “String 类型的对象是不可变的,即没有定义允许您在使用后更改(覆盖)或清零 String 的内容的方法。此功能使 String 对象不适合存储安全敏感信息,例如用户密码。您应该始终将安全敏感信息收集并存储在 char 数组中。” http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx

所以我不能使用EditText,因为它在内部使用字符串(即使它返回一个可以想象由char []或Char []支持的可编辑?)。

从用户那里接受 char 数组的最简单方法是什么?我猜是我在其上监听关键事件的 Canvas?

4

3 回答 3

11

我没有看到 EditText.java (API 17) 在内部使用字符串。它只是 2 页长的代码。当然,EditText 继承的 TextView.java 文件中有 9k 行。您仍然不会看到 TextView.java 在内部使用 String,而是使用自己的 CharWrapper for CharSequence 实现。(TextView.java 行 #8535 API 17)。这里有方法调用 getChars。正如您会注意到的那样,它是从 char[] 而不是 Stringbuf复制过来的。mChars

    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);
    }

现在您所要做的就是调用 getChar 并传递要填写的 char[]。

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

char[] password您无需使用字符串即可获得所需。完成使用后,您可以按如下方式从内存中清除它。

Arrays.fill(password, ' ');
于 2013-04-05T21:55:36.730 回答
0

您的应用程序可能会遇到两种可能的情况:

  1. 所有应用程序都在其环境中进行了适当的沙盒处理。在这种情况下,您不必担心您的密码,因为其他进程无法访问您的进程内存,无论那里是否有字符串或字节 [] 数组。

  2. 有一个具有超级用户访问权限的流氓应用程序。在这种情况下,您也不应该担心字符串,因为有太多地方可以截获您的密码,所以字符串应该接近要担心的事情列表的底部。

于 2012-05-01T09:23:49.677 回答
-1

Editableimplements CharSequence,根据文档,它是一个“可读的char值序列”。

于 2012-05-01T06:26:14.303 回答