2012-09-30 29 views
72

Estoy haciendo una aplicación para Windows, en la que primero debe iniciar sesión.
Los detalles de la cuenta constan de nombre de usuario y contraseña, y deben guardarse localmente.
Es solo una cuestión de seguridad, por lo que otras personas que usan la misma computadora no pueden ver los datos personales de todos.
¿Cuál es la mejor/la manera más segura de guardar esta información? Cómo guardar de forma segura el nombre de usuario/contraseña (local)?

No quiero usar una base de datos, por lo que intentaron algunas cosas con archivos de recursos.
Pero dado que soy algo nuevo con esto, no estoy del todo seguro de lo que estoy haciendo y de dónde debería buscar una solución.

+4

Antes que nada, no guarde la contraseña. Hash it (posiblemente con un valor de sal), y guardar eso en su lugar. – carlosfigueira

+0

"Usuarios" ¿te refieres a usuarios habituales de Windows u otra cosa? (Creo que te refieres a que algunos de tus propios "usuarios" ya que los usuarios normales de Windows ya no pueden ver los datos de los demás ...) –

+0

He editado tu título. Por favor, consulte: "[¿Las preguntas deberían incluir" etiquetas "en sus títulos?] (Http://meta.stackexchange.com/questions/19190/)", donde el consenso es "no, no deberían". –

Respuesta

120

Si solo va a verificar/validar el nombre de usuario y contraseña ingresados, use la clase Rfc2898DerivedBytes (también conocida como Función de derivación de clave basada en contraseña 2 o PBKDF2). Esto es más seguro que usar cifrado como Triple DES o AES porque no hay una forma práctica de pasar del resultado de RFC2898DerivedBytes a la contraseña. Solo puede pasar de una contraseña al resultado. Vea Is it ok to use SHA1 hash of password as a salt when deriving encryption key and IV from password string? para un ejemplo y discusión para .Net o String encrypt/decrypt with password c# Metro Style para WinRT/Metro.

Si está almacenando la contraseña para su reutilización, como el suministro a un tercero, utilice el Windows Data Protection API (DPAPI). Esto utiliza claves protegidas y generadas por el sistema operativo y el algoritmo de cifrado Triple DES para cifrar y descifrar información. Esto significa que su aplicación no tiene que preocuparse por generar y proteger las claves de cifrado, una preocupación importante al usar la criptografía.

En C#, use la clase System.Security.Cryptography.ProtectedData. Por ejemplo, para cifrar un pedazo de datos, utilice ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes(). 
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector) 
byte[] entropy = new byte[20]; 
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider()) 
{ 
    rng.GetBytes(entropy); 
} 

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy, 
    DataProtectionScope.CurrentUser); 

tienda de la entropía y el texto cifrado de forma segura, como en un archivo o clave de registro con los permisos definidos de modo que sólo el usuario actual puede leerlo. Para conseguir el acceso a los datos originales, utilice ProtectedData.Unprotect():

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy, 
    DataProtectionScope.CurrentUser); 

Tenga en cuenta que existen consideraciones de seguridad adicionales. Por ejemplo, evite almacenar secretos como contraseñas como string.Las cadenas son inmutables, ya que no se pueden notificar en la memoria para que alguien que esté mirando la memoria de la aplicación o un volcado de memoria pueda ver la contraseña. Use SecureString o un byte [] en su lugar y recuerde desecharlos o ponerlos en cero tan pronto como ya no necesite la contraseña.

+0

Hola, probé esto, pero recibí un error en entropy = rng.GetBytes (20) diciendo: No se puede convertir de int a byte [] – Robin

+0

@CrispyGMR He corregido ese fragmento de código en la respuesta. Buena atrapada. – akton

+0

Muchas gracias. Usé md5 para hash al principio, pero era un poco escéptico al respecto. Esto parece mucho más seguro. Una pregunta más sin embargo. Quiero guardar bastantes datos como este en un archivo de texto. Veo que son solo un montón de caracteres aleatorios cuando abro mi archivo, pero ¿es lo suficientemente seguro para hacer esto? ¿O recomiendas otra forma de almacenar los datos? – Robin

6

he utilizado esto antes y creo que con el fin de asegurarse de credencial de persistir y de la mejor manera segura es

  1. que puede escribirlos en el archivo de la aplicación de configuración utilizando la clase ConfigurationManager
  2. proteger la contraseña usando la clase SecureString
  3. y luego encriptarla usando herramientas en el espacio de nombres Cryptography.

Este enlace será de gran ayuda espero: Click here

3

DPAPI es sólo para este propósito. Use DPAPI para encriptar la contraseña la primera vez que ingresa el usuario, guárdela en una ubicación segura (el registro del usuario, el directorio de datos de la aplicación del usuario, son algunas opciones). Cada vez que se inicie la aplicación, verifique la ubicación para ver si su clave existe, si usa DPAPI para descifrarla y permitir el acceso, de lo contrario, denieguela.

Cuestiones relacionadas