【问题标题】:Getting a char array from the user without using a String在不使用字符串的情况下从用户获取 char 数组
【发布时间】:2012-05-10 18:12:38
【问题描述】:

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

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

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

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

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

【问题讨论】:

标签: android string security textview


【解决方案1】:

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

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

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

您在不使用字符串的情况下拥有所需的char[] password。完成使用后,您可以按如下方式从内存中清除它。

Arrays.fill(password, ' ');

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 该分析同样适用于桌面和服务器系统,不是吗?然而,Oracle 发布了不要将字符串用于安全敏感数据的指南。他们提供了一个 API 来获取 char[] 中的密码。我认为我们应该将核心转储视为泄漏字符串数据的主要方式。这既不需要 root 也不需要沙盒渗透。
    • 由于大多数安卓输入法在内部使用字符串,你可能不仅需要实现EditText,还需要实现BrainWave-to-byte[]功能。
    • 仅当您建议通过 IME 过滤安全敏感数据时。基本上,通过指向更大的安全漏洞来回应有关安全漏洞的询问是所有论点中最没有说服力的。它没有解决最初的问题,它只是说“我想到了更糟糕的事情”。我同意。你有。
    • 从核心转储的角度来看,Stringbyte[] 之间没有明显区别。
    • 是的,你是对的。在进行 coredump 时,String 和 byte [] 之间没有显着差异。但是,在进行 coredump 之前,有两个显着的区别 - (1) 字符串是不可变的,以及 (2) 字符串可以被实习。 byte [] 没有这些品质。在我处理完 byte[] 中的安全敏感数据后,我可以将其归零,并确保它已从我的内存映像中消失。字符串不是这样。
    【解决方案3】:

    Editable 实现 CharSequence,根据文档,它是“char 值的可读序列”。

    【讨论】:

    • 是的,不幸的是,String也是如此,而String是EditText内部使用的
    猜你喜欢
    • 2018-06-06
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    • 2012-05-24
    • 2023-03-18
    • 2019-06-11
    • 2015-02-13
    • 2014-09-20
    相关资源
    最近更新 更多