He leído que para las contraseñas, es más ideal para su uso char[]
ya que Strings
son inmutables. El problema es que necesito para pasar un argumento de la contraseña a un tercer partido de la dependencia que invoca una llamada http. Sólo se acepta cadenas. La llamada consiste en el envío de una contraseña en el mensaje, así que utilizo el método:
new Request.Builder()
.url("notmyapi.com/login")
.method("POST", new FormBody.Builder()
.add("name", username)
.add("password", password)
.build())
.build()
Sé que es probable que el mal Web API se acaba aceptando una contraseña, ya que es en lugar de aceptar una versión base 64 o lo que sea, pero no es la mía, y yo simplemente tiene que hacer mi trabajo.
Pregunta:
Desde ahora estoy pasando alrededor de la contraseña como char[]
, pero el .add(key, value)
método anterior sólo acepta una cadena, ¿es seguro hacerlo .add("password", new String(password))
? ¿Esto no crea una nueva instancia de String en la memoria lo que estoy tratando de evitar supuestamente por motivos de seguridad?
He leído que para las contraseñas, es más ideal para su uso
char[]
ya queStrings
son inmutables.
Eso no es (toda) la razón. El razonamiento real es:
Está utilizando contraseñas de seguridad.
Un chico malo puede ser capaz de obtener un volcado de memoria de una JVM corriendo ... o extraer un volcado parcial de los bloques de disco que se espera (o se mantiene) páginas de memoria de la JVM. Eso volcado puede contener contraseñas en texto claro.
Para mitigar esto, uno puede (debe) sobrescribir la memoria que contiene las contraseñas cuando ya no son necesarios.
Es difícil sobrescribir un
String
puesto que es inmutable.
Sin embargo, si se examina cada uno de estos puntos, hay supuestos que pueden ser cuestionadas.
Las contraseñas no son una buena manera de implementar la seguridad. Para mayor seguridad de alto grado que debería ser utilizando la clave pública / privada o la autenticación de clave secreta. Así que, o se habla de contraseñas que son "menos importante" a su sistema ... o si tiene un problema mayor que el que usted está tratando de resolver aquí.
Si el malo puede leer la memoria JVM o el archivo de página, que son bastante profundamente en su infraestructura. Ya se ven comprometidos fatalmente. Por otra parte, si se encuentran en este profundo, que pueden muy probablemente a encontrar otras maneras de robar las contraseñas; por ejemplo, el robo de su clave privada del certificado SSL y snooping / decodificar el tráfico de red cifrada.
Esta es sólo una de mitigación:
- Las contraseñas estarán en el claro en el
char[]
por un período. - Antes de las contraseñas llegan a su código, lo más probable se han convertido en
String
objetos de la pila servlet (o cualquier marco que se utiliza). - Además, esta mitigación sólo es eficaz si no sobrescribir el
char[]
en el código.
- Las contraseñas estarán en el claro en el
De hecho, si usted está realmente preocupado por esto, es posible utilizar la reflexión para borrar una cadena; es decir, para mutar un
String
objeto. En general, esto es algo peligroso. Para la comprobación de contraseñas / contraseña, esto podría ser aceptable.
En resumen, yo diría que el uso char[]
en lugar de String
es demasiado costoso de implementar en Java .... a menos que esté preparado para volver a desarrollar por completo su framework de desarrollo web. Por otra parte, el beneficio de hacer esto discutible, teniendo en cuenta las otras formas en que alguien con acceso profunda podría robar las contraseñas.
Ahora a su pregunta específica:
¿Es seguro hacer
.add("password", new String(password))
Si se tiene en cuenta que sea arriesgado utilizar un String
una contraseña, luego de que el código no ayuda. De hecho, si se asume que password
es un String
ahora tiene dos String
objetos en memoria que contienen el texto de la contraseña.
Si la API que está utilizando, debe proporcionar la contraseña como
String
usted tiene un problema.Si la fuente de la contraseña (es decir, cómo se obtiene de la interfaz de usuario, el marco servlet, lo que sea) es una
String
, tiene un problema.En ambos casos será necesario volver a trabajar aspectos del código que se está interactuando con el de resolver el problema. Esto puede ser difícil.
Y:
Sé que es probable que el mal Web API se acaba aceptando una contraseña, ya que es en lugar de aceptar una versión base 64 o lo que sea.
Base64 no ralentizará el malo de la película durante más de un minuto o así. Lo mismo vale para cualquier codificación reversible. Pero espero que insisten en que la contraseña sólo se enviará a través de SSL / TLS conexiones seguras.