2012-05-01 15 views
9

Deseo adquirir una cadena de contraseña del usuario en Android.Obteniendo una matriz char del usuario sin usar un String

No quiero que esta cadena se almacene en Java String en ningún punto del proceso desde que el usuario lo escribe, hasta donde llega a mi código en una matriz de caracteres o de bytes.

El motivo es el mandato de Sun contra el uso de cadenas de Java para datos confidenciales. "Los objetos de tipo cadena son inmutables, es decir, no hay métodos definidos que le permitan cambiar (sobrescribir) o poner a cero el contenido de una cadena después del uso. Esta característica hace que los objetos String no sean aptos para almacenar información sensible a la seguridad como el usuario contraseñas. En su lugar, siempre debe recopilar y almacenar información confidencial de seguridad en una matriz de caracteres ". http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx

así que no puedo usar EditarTexto, debido a que utiliza cadenas internamente (a pesar de que devuelve un editable, que posiblemente podría ser respaldado por char [] o Char []?).

¿Cuál es la forma más simple de aceptar una matriz de caracteres del usuario? Estoy adivinando un lienzo en el que escucho eventos clave?

+0

Use una secuencia de caracteres Char, tal vez? – Sparky

+0

Le sugiero que lea esto si aún no lo ha hecho: http://www.mail-archive.com/[email protected]/msg01647.html –

+0

Gracias por el enlace a esa discusión. La discusión refleja el argumento ofrecido por Lenik a continuación.Lo descarto por las razones en el comentario adjunto a su sugerencia. –

Respuesta

-1

Editable implementa CharSequence, que, de acuerdo con los documentos, es una "secuencia legible de valores char".

+0

Sí, desafortunadamente, también lo hace String, y String es lo que se usa internamente en EditText –

0

Hay dos situaciones posibles que su aplicación puede encontrarse:

  1. todas las aplicaciones están adecuadamente arena en caja en su entorno. En este caso, no debe preocuparse por sus contraseñas, ya que otros procesos no pueden acceder a su memoria de proceso, sin importar si hay matrices de cadenas o bytes [] allí.

  2. Hay una aplicación deshonesta con acceso de superusuario. En este caso, tampoco debe preocuparse por las cadenas, porque hay demasiados lugares para interceptar sus contraseñas, por lo que Strings debería estar cerca de la parte inferior de la lista de cosas de las que preocuparse.

+1

Ese análisis se aplicaría igualmente a sistemas de escritorio y servidor, ¿no es así? Y, sin embargo, Oracle emitió la guía para no utilizar cadenas para datos confidenciales de seguridad. Y proporcionaron una API para obtener passwds en un char []. Creo que deberíamos considerar los núcleos como la forma principal de filtrar los datos de String. Eso no requiere penetración de root o sandbox. –

+1

Dado que la mayoría de los IME de Android usan cadenas internas, es posible que necesite implementar no solo 'EditText', sino también la funcionalidad' BrainWave-to-byte [] '. – lenik

+0

Solo si propone filtrar datos confidenciales a través de un IME. Básicamente, responder a una consulta sobre un agujero de seguridad apuntando a un agujero de seguridad más grande es el menos convincente de todos los argumentos. No aborda el problema original, solo dice "he pensado en algo peor". Estoy de acuerdo. Tienes. –

6

No veo el EditText.java (API 17) usando la cadena internamente. Es solo un código de 2 páginas de largo. Por supuesto, TextView.java del que EditText ha heredado tiene 9k líneas en el archivo. Aún no verá TextView.java utilizando la cadena internamente, pero con su propia implementación de CharWrapper para CharSequence. (TextView.java línea # 8535 API 17). Aquí tienes el método llamado getChars. Como notará que buf se copia desde mChars que es char [] y no 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); 
    } 

Ahora todo lo que tiene que hacer es llamar getChar y pasar a lo largo del char [] para ser rellenado.

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

Has deseado char[] password sin utilizar cuerdas. Una vez que haya terminado de trabajar con él, puede borrarlo de la memoria de la siguiente manera.

Arrays.fill(password, ' '); 
Cuestiones relacionadas