¿Por qué se prefiere char[] a String para las contraseñas?

Resuelto Ahamed asked hace 12 años • 17 respuestas

En Swing, el campo de contraseña tiene un método getPassword()(devuelve char[]) en lugar del método habitual getText()(devuelve String). De manera similar, me encontré con una sugerencia de no utilizarla Stringpara manejar contraseñas.

¿Por qué Stringsupone una amenaza para la seguridad cuando se trata de contraseñas? Se siente incómodo de usar char[].

Ahamed avatar Jan 16 '12 21:01 Ahamed
Aceptado

Las cadenas son inmutables . Eso significa que una vez que haya creado el archivo String, si otro proceso puede volcar la memoria, no hay manera (aparte de la reflexión ) de deshacerse de los datos antes de que se active la recolección de basura .

Con una matriz, puedes borrar explícitamente los datos una vez que hayas terminado. Puede sobrescribir la matriz con lo que desee y la contraseña no estará presente en ninguna parte del sistema, incluso antes de la recolección de basura.

Así que sí, esto es un problema de seguridad, pero incluso usarlo char[]solo reduce la ventana de oportunidad para un atacante, y es solo para este tipo específico de ataque.

Como se señaló en los comentarios, es posible que las matrices que el recolector de basura mueve dejen copias perdidas de los datos en la memoria. Creo que esto es específico de la implementación: el recolector de basura puede borrar toda la memoria a medida que avanza para evitar este tipo de cosas. Incluso si lo hace, todavía existe el tiempo durante el cual char[]contiene los personajes reales como una ventana de ataque.

Jon Skeet avatar Jan 16 '2012 14:01 Jon Skeet

Si bien otras sugerencias aquí parecen válidas, hay otra buena razón. Con Plain Stringtienes muchas más posibilidades de imprimir accidentalmente la contraseña en registros , monitores o algún otro lugar inseguro. char[]es menos vulnerable.

Considera esto:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

Huellas dactilares:

String: Password
Array: [C@5829428e
Konrad Garus avatar Jan 16 '2012 19:01 Konrad Garus

Para citar un documento oficial, la guía de Arquitectura de criptografía de Java dice esto sobre las contraseñas char[]versus String(sobre el cifrado basado en contraseñas, pero, por supuesto, se trata más generalmente de contraseñas):

Parecería lógico recopilar y almacenar la contraseña en un objeto de tipo java.lang.String. Sin embargo, aquí está la advertencia: Objectlos mensajes de tipo Stringson inmutables, es decir, no hay métodos definidos que le permitan cambiar (sobrescribir) o poner a cero el contenido de un String uso posterior. Esta característica hace que Stringlos objetos no sean adecuados para almacenar información confidencial de seguridad, como contraseñas de usuario. En su lugar , siempre debe recopilar y almacenar información confidencial sobre seguridad en una charmatriz.

La pauta 2-2 de las Pautas de codificación segura para el lenguaje de programación Java, versión 4.0 también dice algo similar (aunque originalmente está en el contexto del registro):

Directriz 2-2: No registre información altamente confidencial

Parte de la información, como los números de Seguro Social (SSN) y las contraseñas, es muy confidencial. Esta información no debe conservarse por más tiempo del necesario ni donde pueda ser vista, ni siquiera por los administradores. Por ejemplo, no debe enviarse a archivos de registro y su presencia no debe ser detectable mediante búsquedas. Algunos datos transitorios pueden conservarse en estructuras de datos mutables, como matrices de caracteres, y borrarse inmediatamente después de su uso. Borrar estructuras de datos ha reducido la efectividad en los sistemas típicos de tiempo de ejecución de Java, ya que los objetos se mueven en la memoria de forma transparente para el programador.

Esta directriz también tiene implicaciones para la implementación y el uso de bibliotecas de nivel inferior que no tienen conocimiento semántico de los datos con los que están tratando. Por ejemplo, una biblioteca de análisis de cadenas de bajo nivel puede registrar el texto en el que trabaja. Una aplicación puede analizar un SSN con la biblioteca. Esto crea una situación en la que los SSN están disponibles para los administradores con acceso a los archivos de registro.

Bruno avatar Jan 17 '2012 03:01 Bruno