Almacenar credenciales de forma segura con PasswordVault

Un problema al que nos enfrentamos cuando tenemos que almacenar credenciales de nuestros usuarios en una aplicación móvil, es el como hacerlo de forma segura. Por muy seguro que un sistema afirme ser, siempre lo será tanto como su parte menos segura. Por lo que guardar el nombre y password de un usuario en los settings o en el almacenamiento local de nuestra aplicación sin cifrado de ningún tipo, es una negligencia gravísima. Bastará tener acceso al sistema de archivos por parte de un atacante para obtener esos datos.

Existen muchas formas de evitar esto. Y todas pasan de alguna forma por encriptar los datos almacenados. Quizás podríamos pensar que nos podríamos proteger simplemente calculando un hash del password y usar este hash para autentificar a nuestro usuario en el backend. Esto uede funcionar si el servicio de backend que usamos está bajo nuestro control o siendo de terceros admite esta opción. Pero en la gran mayoría de casos el backend nos pedirá un usuario y password. Incluso en el caso de poder usar el hash de un password, almacenarlo en texto plano junto al nombre de usuario es ya una información muy valiosa para un atacante.

En Windows 8.1 y Windows Phone 8.1 (Tanto Windows XAML como Silverlight) disponemos de un API llamada PasswordVault, que representa un almacén seguro para credenciales de usuario. Una aplicación solo podrá acceder a las credenciales almacenadas por ella misma y no a los de otras aplicaciones. Usarla además es realmente sencillo.

PasswordVault nos permite guardar las credenciales de un usuario mediante el método Add, pasándole una instancia de la clase PasswordCredential. El constructor de PasswordCredential nos permite indicar tres valores:

  • Resource, un nombre que identifica la credencial que se está creando.
  • UserName, el nombre del usuario… lógico no?
  • Password, el password.
PasswordCredential
var credential = new PasswordCredential(«AppName_userCredentials», userEmail, userPassword);

Una vez creado, solo tenemos que pasarlo al método Add de nuestra instancia de PasswordVault:

PasswordVault Add method
PasswordVault pVault = new PasswordVault();
pVault.Add(credential);

Y ya hemos guardado nuestras credenciales de forma segura. Para recuperar los datos cuando los necesitemos de nuevo, podemos usar el método FindAllByResource. Este método recibe un parámetro con el nombre de recurso que indicamos al crear la credencial y devuelve una lista con todas las credenciales que coincidan con ese nombre:

FindAllByResource
PasswordVault pVault = new PasswordVault();
var credentials = pVault.FindAllByResource(resourceName);
return credentials.FirstOrDefault();

Es muy importante que, si existe la posibilidad de que al pedir las credenciales, estas no existan, envolvamos la llamada a FindAllByResource en un bloque Try/Catch. En vez de simplemente devolver nulo, el método falla con una excepción si no existen.

Tras obtener la credencial, podremos obtener directamente el nombre de usuario pero para poder acceder al password tendremos primero que usar el método RetrievePassword de la instancia de PasswordCredential con la que estemos trabajando.

RetrievePassword
var credential = credentials.First();
credential.RetrievePassword();

Tras esto podremos acceder al password almacenado usando la propiedad Password de PasswordCredential.

Por último, puede que en algún momento el usuario quiera que dejemos de almacenar sus credenciales, por lo que podremos usar el método Remove, para eliminarlas del PasswordVault.

PasswordVault Remove
var credentials = this.pVault.FindAllByResource(resourceName);
var credential = credentials.First();
if (credential != null)
    this.pVault.Remove(credential);

En este sentido es interesante tener en cuenta algo. Cuando desinstalemos la aplicación, las credenciales guardadas en el PasswordVault no serán eliminadas. Cuando guardamos algo en los settings o el almacenamiento local de nuestra aplicación, al desinstalar se elimina todo. Esto no ocurre con las credenciales guardadas en el PasswordVault, pues usan un almacenamiento central del sistema.

Y esto es todo! Usar PasswordVault es muy fácil y añade un extra de seguridad a nuestra aplicación, así que no hay excusa para no usarlo. Aquí os dejo una aplicación universal de ejemplo con el código MVVM y el servicio de credenciales compartido. Espero que os sea de utilidad.

Un saludo y Happy Coding!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *